我只需要你做最小量的修改实现目标,刚刚的RoutePlanActivity代码如下:package com.example.bus;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.*;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.RouteSearch;
import java.util.ArrayList;
import java.util.List;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.services.route.BusPath;
public class RoutePlanActivity extends AppCompatActivity implements RouteSearch.OnRouteSearchListener {
// ✅ 新增:定义来源类型常量
public static final String EXTRA_SOURCE = "extra_source";
public static final int SOURCE_FROM_HOME_SEARCH = 1001;
public static final int SOURCE_FROM_MAP_DIRECT = 1002;
private MapView mapView;
private AMap aMap;
private RouteSearch routeSearch;
private RecyclerView recyclerSteps;
private boolean isSearching = false;
// ✅ 新增:记录来源类型
private int sourceType = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_route_plan);
// ✅ 新增:获取来源类型
sourceType = getIntent().getIntExtra(EXTRA_SOURCE, -1);
mapView = findViewById(R.id.map_view);
recyclerSteps = findViewById(R.id.recycler_steps);
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
}
try {
routeSearch = new RouteSearch(this);
} catch (AMapException e) {
throw new RuntimeException(e);
}
routeSearch.setRouteSearchListener(this);
parseIntentAndStartSearch();
}
/**
* 解析 Intent 并发起公交路线搜索
*/
private void parseIntentAndStartSearch() {
if (isSearching) return;
double targetLat = getIntent().getDoubleExtra("target_lat", 0);
double targetLng = getIntent().getDoubleExtra("target_lng", 0);
if (targetLat == 0 || targetLng == 0) {
Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show();
finish();
return;
}
// 起点:模拟当前位置
LatLonPoint start = new LatLonPoint(39.909186, 116.397411); // 北京
LatLonPoint target = new LatLonPoint(targetLat, targetLng);
RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(start, target);
RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT, "全国", 0);
query.setCityd("全国"); // 支持跨城
isSearching = true;
routeSearch.calculateBusRouteAsyn(query); // ✅ 异步调用,无需 try-catch
}
@Override
public void onBusRouteSearched(BusRouteResult result, int rCode) {
isSearching = false;
if (rCode != 1000 || result == null || result.getPaths().isEmpty()) {
Toast.makeText(this, "未找到公交路线", Toast.LENGTH_SHORT).show();
finish();
return;
}
BusPath bestPath = result.getPaths().get(0);
// ✅ 手动绘制路线(替代 BusRouteOverlay)
drawRouteOnMap(bestPath);
// 显示换乘步骤
StepAdapter adapter = new StepAdapter(bestPath.getSteps());
recyclerSteps.setLayoutManager(new LinearLayoutManager(this));
recyclerSteps.setAdapter(adapter);
// 显示总时间和票价
String info = String.format("耗时:%d分钟 | 票价:¥%.2f",
bestPath.getDuration() / 60, bestPath.getCost());
Toast.makeText(this, info, Toast.LENGTH_LONG).show();
}
/**
* 手动绘制公交路线 Polyline
*/
private void drawRouteOnMap(BusPath path) {
aMap.clear();
List<LatLng> allPoints = new ArrayList<>();
for (BusStep step : path.getSteps()) {
boolean added = false;
// 1. 【公交】尝试通过反射获取 getPolyline()
if (step.getBusLine() != null) {
try {
java.lang.reflect.Method method = step.getBusLine().getClass().getMethod("getPolyline");
Object result = method.invoke(step.getBusLine());
if (result instanceof java.util.List) {
for (Object obj : (java.util.List<?>) result) {
if (obj instanceof LatLonPoint) {
LatLonPoint point = (LatLonPoint) obj;
allPoints.add(new LatLng(point.getLatitude(), point.getLongitude()));
added = true;
}
}
}
} catch (Exception e) {
Log.d("RoutePlan", "BusLine.getPolyline() 不可用: " + e.getMessage());
}
}
// 2. 【步行】反射获取 walk polyline
if (!added && step.getWalk() != null) {
try {
java.lang.reflect.Method method = step.getWalk().getClass().getMethod("getPolyline");
Object result = method.invoke(step.getWalk());
if (result instanceof java.util.List) {
for (Object obj : (java.util.List<?>) result) {
if (obj instanceof LatLonPoint) {
LatLonPoint point = (LatLonPoint) obj;
allPoints.add(new LatLng(point.getLatitude(), point.getLongitude()));
added = true;
}
}
}
} catch (Exception e) {
Log.d("RoutePlan", "WalkPath.getPolyline() 不可用: " + e.getMessage());
}
}
// 3. 【地铁/换乘】使用 getEntrance() 和 getExit() -> Doorway -> LatLonPoint
if (!added) {
Doorway entrance = step.getEntrance(); // 返回 Doorway!
Doorway exit = step.getExit(); // 返回 Doorway!
if (entrance != null && entrance.getLatLonPoint() != null) {
LatLonPoint p = entrance.getLatLonPoint();
allPoints.add(new LatLng(p.getLatitude(), p.getLongitude()));
added = true;
}
if (exit != null && exit.getLatLonPoint() != null) {
LatLonPoint p = exit.getLatLonPoint();
allPoints.add(new LatLng(p.getLatitude(), p.getLongitude()));
added = true;
}
if (added) {
Log.d("RoutePlan", "使用 Doorway 坐标近似绘制路段");
}
}
}
// === 绘制折线 ===
if (!allPoints.isEmpty()) {
PolylineOptions options = new PolylineOptions()
.addAll(allPoints)
.color(0xFF4A90E2)
.width(12f)
.geodesic(false);
aMap.addPolyline(options);
// 聚焦地图
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng latLng : allPoints) {
builder.include(latLng);
}
try {
LatLngBounds bounds = builder.build();
aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
} catch (Exception e) {
Log.e("RoutePlan", "边界计算失败", e);
}
} else {
Toast.makeText(this, "无法获取路线坐标", Toast.LENGTH_SHORT).show();
}
}
// ✅ 新增:重写返回键,根据来源决定跳转行为
@Override
public void onBackPressed() {
if (sourceType == SOURCE_FROM_MAP_DIRECT) {
// 来自地图直接跳转:回到主页面并打开地图 Tab
Intent mainIntent = new Intent(this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mainIntent.putExtra("open_tab", "map"); // 可选:通知 MainActivity 切换到地图
startActivity(mainIntent);
finish(); // 关闭当前页面
} else {
// 默认情况:正常返回上一页(如 SearchResultActivity)
super.onBackPressed();
}
}
// 其他不需要处理的回调
@Override public void onDriveRouteSearched(DriveRouteResult r, int c) {}
@Override public void onWalkRouteSearched(WalkRouteResult r, int c) {}
@Override public void onRideRouteSearched(RideRouteResult r, int c) {}
// 生命周期方法保持不变
@Override protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override protected void onDestroy() {
if (mapView != null) mapView.onDestroy();
if (routeSearch != null) routeSearch.setRouteSearchListener(null);
super.onDestroy();
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
第一,我希望按照MainActivity的方式获取用户位置,MainActivity代码如下:package com.example.bus;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.example.bus.databinding.ActivityMainBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private static final String SAVED_NAV_ID = "saved_nav_id";
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ✅ 添加日志:查看冷启动时权限是否已被系统撤销
Log.d("PERMISSION_DEBUG", "onCreate: FINE_LOCATION_GRANTED = " +
(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED));
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
BottomNavigationView navView = findViewById(R.id.nav_view);
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home,
R.id.navigation_map,
R.id.navigation_settings)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
// ✅ 更新底部导航逻辑
navView.setOnItemSelectedListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.navigation_map) {
ensureFineLocationPermission(() -> {
if (navController.getCurrentDestination().getId() != R.id.navigation_map) {
navController.navigate(R.id.navigation_map);
}
});
return true;
}
navController.navigate(itemId);
return true;
});
// 恢复上次选中的底部菜单项
if (savedInstanceState != null) {
int savedId = savedInstanceState.getInt(SAVED_NAV_ID, R.id.navigation_home);
navView.setSelectedItemId(savedId);
}
}
// ✅ 新增:通用权限保障方法(所有进地图前都必须走这里)
public void ensureFineLocationPermission(Runnable onGranted) {
boolean hasFine = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
if (hasFine) {
onGranted.run(); // 权限存在,直接执行
} else {
requestFineLocationPermission(onGranted); // 否则发起请求
}
}
/**
* 请求精确定位权限(带解释说明)
*/
private void requestFineLocationPermission(Runnable onGranted) {
boolean hasFine = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
if (hasFine) {
onGranted.run();
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
new AlertDialog.Builder(this)
.setTitle("需要精确定位权限")
.setMessage("为了准确查找您附近的公交站点和车辆位置,本应用需要获取您的精确位置。\n否则将无法使用地图相关功能。\n\n请务必选择【允许】或【仅限这一次】。")
.setPositiveButton("去允许", (d, w) -> requestFineLocation())
.setNegativeButton("取消", null)
.show();
} else {
requestFineLocation();
}
}
private void requestFineLocation() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
boolean hasFine = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
if (hasFine) {
Toast.makeText(this, "已获得精确定位权限", Toast.LENGTH_SHORT).show();
navigateToMapIfNeeded();
} else {
boolean hasCoarse = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
if (hasCoarse) {
new AlertDialog.Builder(this)
.setTitle("需要精确位置")
.setMessage("检测到您使用的是【大致位置】,这会导致地图功能无法正常使用。\n\n" +
"请在设置中将定位权限修改为【精确位置】。")
.setPositiveButton("去设置", (d, w) -> openAppSettings())
.setNegativeButton("取消", null)
.show();
} else {
Toast.makeText(this, "定位权限未授予,无法使用地图功能", Toast.LENGTH_LONG).show();
}
}
}
}
private void navigateToMapIfNeeded() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
if (navController.getCurrentDestination().getId() != R.id.navigation_map) {
navController.navigate(R.id.navigation_map);
}
}
private void openAppSettings() {
Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
BottomNavigationView navView = findViewById(R.id.nav_view);
outState.putInt(SAVED_NAV_ID, navView.getSelectedItemId());
}
}第二,我希望这个代码能够区分是从哪个界面进入的。如果从SearchFragment进入,我需要他真实获取用户位置信息为起点,在SearchResultActivity中输入的信息为终点规划公交路线。如果是从MapFragment进入的,我需要把MapFragment中输入的起点作为线路的起点,MapFragment中输入的终点作为线路的终点。然后,activity_route_plan.xml代码如下:<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_marginTop="?attr/actionBarSize">
<!-- 地图区域(占上面 60%) -->
<com.amap.api.maps.MapView
android:id="@+id/map_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/recycler_steps"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.6" />
<!-- 步骤列表(下方 40%) -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_steps"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#f5f5f5"
android:elevation="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.4" />
</androidx.constraintlayout.widget.ConstraintLayout>
我需要你这顶部添加一个返回键,如果是从SearchResultActivity中进来的就返回到SearchResultActivity去。如果是从MapFragment就返回到MapFragment去。相关代码SearchResultActivity如下:package com.example.bus;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import java.util.ArrayList;
import java.util.List;
public class SearchResultActivity extends AppCompatActivity implements PoiSearch.OnPoiSearchListener {
private EditText searchInput;
private Button searchBtn, goToBtn;
private RecyclerView resultListView;
private List<PoiItem> poiList = new ArrayList<>();
private ResultAdapter adapter;
private PoiSearch poiSearch;
// 地图相关
private MapView mapView;
private AMap aMap;
private Marker selectedMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
// 设置 ActionBar 返回按钮
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("搜索地点");
}
initViews();
setupMap(savedInstanceState); // 初始化地图
setupSearch(); // 初始化搜索
}
private void initViews() {
searchInput = findViewById(R.id.search_input);
searchBtn = findViewById(R.id.search_btn);
resultListView = findViewById(R.id.result_list);
goToBtn = findViewById(R.id.btn_go_to);
goToBtn.setEnabled(false);
}
private void setupMap(Bundle savedInstanceState) {
mapView = findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setScrollGesturesEnabled(true);
aMap.setOnMapClickListener(latLng -> {
if (selectedMarker != null) selectedMarker.remove();
selectedMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("选中位置"));
goToBtn.setEnabled(true);
});
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.909186, 116.397411), 10f));
}
}
private void setupSearch() {
String keyword = getIntent().getStringExtra("keyword");
if (keyword != null && !keyword.isEmpty()) {
searchInput.setText(keyword);
performSearch(keyword);
}
searchBtn.setOnClickListener(v -> {
String text = searchInput.getText().toString().trim();
if (!text.isEmpty()) {
performSearch(text);
} else {
Toast.makeText(this, "请输入关键词", Toast.LENGTH_SHORT).show();
}
});
goToBtn.setOnClickListener(v -> {
if (selectedMarker != null) {
LatLng pos = selectedMarker.getPosition();
navigateToRoute(pos.latitude, pos.longitude, "地图选点");
} else if (!poiList.isEmpty()) {
PoiItem item = poiList.get(0);
LatLonPoint p = item.getLatLonPoint();
navigateToRoute(p.getLatitude(), p.getLongitude(), item.getTitle());
} else {
Toast.makeText(this, "暂无目标位置", Toast.LENGTH_SHORT).show();
}
});
}
private void navigateToRoute(double lat, double lng, String title) {
Intent intent = new Intent(this, RoutePlanActivity.class);
intent.putExtra("start_mode", "my_location");
intent.putExtra("target_lat", lat);
intent.putExtra("target_lng", lng);
intent.putExtra("target_title", title);
startActivity(intent);
}
private void performSearch(String keyword) {
PoiSearch.Query query;
if (isLikelyBusStop(keyword)) {
// 如果像公交站名,加过滤
query = new PoiSearch.Query(keyword, "15", "全国"); // 公共交通类
} else {
// 否则不限类别,确保能搜到地标
query = new PoiSearch.Query(keyword, "", "全国");
}
query.setPageSize(20);
query.setPageNum(0);
try {
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "搜索启动失败", Toast.LENGTH_SHORT).show();
}
}
private boolean isLikelyBusStop(String keyword) {
return keyword.contains("公交") ||
keyword.contains("地铁") ||
keyword.contains("BRT") ||
keyword.endsWith("站") ||
keyword.endsWith("场");
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null) {
poiList.clear();
poiList.addAll(result.getPois());
if (adapter == null) {
adapter = new ResultAdapter(poiList, item -> {
if (selectedMarker != null) selectedMarker.remove();
LatLng latLng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude());
selectedMarker = aMap.addMarker(new MarkerOptions().position(latLng).title(item.getTitle()));
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
goToBtn.setEnabled(true);
});
resultListView.setLayoutManager(new LinearLayoutManager(this));
resultListView.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
goToBtn.setEnabled(!poiList.isEmpty());
} else {
String msg = rCode == 17 ? "高德Key校验失败" : "搜索失败: 错误码=" + rCode;
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Override
public void onPoiItemSearched(PoiItem item, int rCode) {}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if (poiSearch != null) poiSearch.setOnPoiSearchListener(null);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
MapFragment如下:package com.example.bus.ui.map;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.amap.api.maps.MapView;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.LatLng;
//import com.example.bus.R;
//import com.example.bus.databinding.FragmentMapBinding;
import com.amap.api.services.core.AMapException;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.UiSettings;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.example.bus.R;
import com.example.bus.RoutePlanActivity;
import com.example.bus.databinding.FragmentMapBinding;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.core.LatLonPoint;
// MapView 已在 XML 中声明,无需额外 import(会自动识别)
public class MapFragment extends Fragment {
private FragmentMapBinding binding;
private MapView mapView; // 高德地图视图
private AMap aMap; // 地图控制器
private boolean isFirstLocationSet = false; // 防止反复跳转
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// 初始化 ViewModel 和 ViewBinding
binding = FragmentMapBinding.inflate(inflater, container, false);
View root = binding.getRoot();
//绑定 MapView
mapView = root.findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState); // 必须调用生命周期方法
// 初始化地图
initMap();
if (binding.mapSearch != null) {
binding.mapSearch.setOnClickListener(v -> {
String keyword = binding.mapInput2.getText().toString().trim();
if (keyword.isEmpty()) {
Toast.makeText(requireContext(), "请输入终点", Toast.LENGTH_SHORT).show();
return;
}
PoiSearch.Query query = new PoiSearch.Query(keyword, "", "全国");
query.setPageSize(10); // 可选:设置每页数量
query.setPageNum(0); // 可选:第一页
try {
PoiSearch search = new PoiSearch(requireContext(), query);
search.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
@Override
public void onPoiSearched(PoiResult result, int rCode) {
requireActivity().runOnUiThread(() -> {
if (rCode == 1000 && result != null && !result.getPois().isEmpty()) {
PoiItem item = result.getPois().get(0);
LatLonPoint point = item.getLatLonPoint();
Intent intent = new Intent(requireContext(), RoutePlanActivity.class);
intent.putExtra("start_mode", "my_location");
intent.putExtra("target_lat", point.getLatitude());
intent.putExtra("target_lng", point.getLongitude());
intent.putExtra("target_title", item.getTitle());
startActivity(intent);
} else {
handlePoiSearchError(rCode);
}
});
}
@Override
public void onPoiItemSearched(PoiItem item, int rCode) {
// 不使用单个 POI 搜索
}
});
// 发起异步请求(这个方法不会再抛异常了)
search.searchPOIAsyn();
} catch (AMapException e) {
e.printStackTrace();
Toast.makeText(requireContext(), "POI搜索初始化失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
return root;
}
private void handlePoiSearchError(int rCode) {
String errorMsg;
switch (rCode) {
case 1101:
errorMsg = "网络连接异常";
break;
case 1102:
errorMsg = "网络响应超时";
break;
case 1103:
errorMsg = "解析异常";
break;
case 1104:
errorMsg = "请求参数非法";
break;
case 1200:
errorMsg = "API Key 不存在";
break;
case 1202:
errorMsg = "签名验证失败(SHA1/包名不匹配)";
break;
case 1206:
errorMsg = "API Key 权限不足(未开通 POI 搜索服务)";
break;
default:
errorMsg = "未知错误: " + rCode;
break;
}
Toast.makeText(requireContext(), "搜索失败: " + errorMsg, Toast.LENGTH_LONG).show();
}
/**
* 初始化地图
*/
private void initMap() {
if (aMap == null) {
aMap = mapView.getMap();
UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true); // 显示缩放按钮
uiSettings.setCompassEnabled(true); // 显示指南针
uiSettings.setMyLocationButtonEnabled(false); // 我们自己控制定位行为
}
}
@Override
public void onResume() {
super.onResume(); //每次恢复可见时都检查权限状态
mapView.onResume();
// ✅ 直接开启定位图层(信任 MainActivity 的判断)
if (aMap != null) {
aMap.setMyLocationEnabled(true);
// 只第一次进入时移动相机
if (!isFirstLocationSet) {
LatLng defaultLoc = new LatLng(39.909186, 116.397411);
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLoc, 12f));
isFirstLocationSet = true;
}
}
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (mapView != null) {
mapView.onDestroy();
}
binding = null;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
最新发布