package com.example.baiyunmap;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SuggestionResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
import com.baidu.mapapi.search.sug.SuggestionSearch;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.walknavi.WalkNavigateHelper;
import com.baidu.mapapi.walknavi.adapter.IWEngineInitListener;
import com.baidu.mapapi.walknavi.adapter.IWRoutePlanListener;
import com.baidu.mapapi.walknavi.params.WalkNaviLaunchParam;
import com.baidu.mapapi.walknavi.route.WalkRouteNodeInfo;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private MapView mMapView = null;
private BaiduMap mBaiduMap = null;
private LocationClient mLocationClient = null;
private Button mNavigationButton = null;
private EditText mSearchEditText = null;
private Button mSearchButton = null;
private Button mToggleMapTypeButton = null;
private ProgressBar mProgressBar = null;
private ListView mSuggestionListView = null;
private ArrayAdapter<String> mSuggestionAdapter;
private PoiSearch mPoiSearch = null;
private SuggestionSearch mSuggestionSearch = null;
// 广东白云学院坐标(西校区)
private static final LatLng BAIYUN_COLLEGE = new LatLng(23.272513, 113.207609);
private static final float DEFAULT_ZOOM_LEVEL = 18.0f; // 默认缩放级别
private boolean isFirstLocationReceived = false;
private LatLng mCurrentLocation = null; // 存储当前位置
// 步行导航相关
private WalkNavigateHelper mWalkHelper;
private WalkNaviLaunchParam mWalkParam;
// 权限相关
private static final String[] LOCATION_PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
// 步行导航所需权限
private static final String[] WALK_PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
private static final int PERMISSION_REQUEST_CODE = 1;
private static final int WALK_PERMISSION_REQUEST_CODE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 必须在 setContentView 之前初始化 SDK
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
// 初始化步行导航
initWalkNavigation();
// 初始化视图
mMapView = findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
mNavigationButton = findViewById(R.id.btn_navigation);
mSearchEditText = findViewById(R.id.edit_search);
mSearchButton = findViewById(R.id.btn_search);
mToggleMapTypeButton = findViewById(R.id.btn_toggle_map_type);
mProgressBar = findViewById(R.id.progress_bar);
mSuggestionListView = findViewById(R.id.list_suggestions);
// 初始化 PoiSearch
mPoiSearch = PoiSearch.newInstance();
mPoiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(PoiResult result) {
mProgressBar.setVisibility(View.GONE);
if (result == null || result.getAllPoi() == null) {
Toast.makeText(MainActivity.this, "未找到相关地点", Toast.LENGTH_SHORT).show();
return;
}
// 清除地图上已有标注
mBaiduMap.clear();
// 显示搜索结果
for (PoiInfo info : result.getAllPoi()) {
OverlayOptions option = new MarkerOptions().position(info.location).title(info.name);
mBaiduMap.addOverlay(option);
}
// 跳转到第一个搜索结果位置
if (!result.getAllPoi().isEmpty()) {
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(result.getAllPoi().get(0).location);
mBaiduMap.animateMapStatus(update);
}
}
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
// 暂不处理详情结果
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
// 暂不处理室内结果
}
});
// 初始化建议搜索
mSuggestionSearch = SuggestionSearch.newInstance();
mSuggestionSearch.setOnGetSuggestionResultListener(new OnGetSuggestionResultListener() {
@Override
public void onGetSuggestionResult(SuggestionResult res) {
if (res == null || res.getAllSuggestions() == null) {
mSuggestionAdapter.clear();
mSuggestionListView.setVisibility(View.GONE);
return;
}
List<String> suggestions = new ArrayList<>();
for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
suggestions.add(info.key);
}
mSuggestionAdapter.clear();
mSuggestionAdapter.addAll(suggestions);
mSuggestionAdapter.notifyDataSetChanged();
mSuggestionListView.setVisibility(suggestions.isEmpty() ? View.GONE : View.VISIBLE);
}
});
mSuggestionAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
mSuggestionListView.setAdapter(mSuggestionAdapter);
mSuggestionListView.setOnItemClickListener((parent, view, position, id) -> {
String selected = (String) parent.getItemAtPosition(position);
mSearchEditText.setText(selected);
mSuggestionListView.setVisibility(View.GONE);
mPoiSearch.searchInCity(null, selected);
mProgressBar.setVisibility(View.VISIBLE);
});
// 搜索按钮点击事件
mSearchButton.setOnClickListener(v -> {
String keyword = mSearchEditText.getText().toString().trim();
if (!keyword.isEmpty()) {
mSuggestionListView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
mPoiSearch.searchInCity(null, keyword); // 搜索当前城市
} else {
Toast.makeText(this, "请输入搜索内容", Toast.LENGTH_SHORT).show();
}
});
// 设置地图点击监听器,用于获取目标位置
mBaiduMap.setOnMarkerClickListener(marker -> {
LatLng targetLocation = marker.getPosition();
startWalkNavigation(targetLocation);
return true;
});
// 设置地图中心
setMapCenter(BAIYUN_COLLEGE, DEFAULT_ZOOM_LEVEL);
// 导航按钮点击事件
mNavigationButton.setOnClickListener(v -> {
if (mCurrentLocation == null) {
Toast.makeText(MainActivity.this, "正在获取当前位置,请稍后...", Toast.LENGTH_SHORT).show();
return;
}
startWalkNavigation(mCurrentLocation); // 默认导航到当前位置(可自定义)
});
// 地图类型切换按钮点击事件
mToggleMapTypeButton.setOnClickListener(v -> {
if (mBaiduMap.getMapType() == BaiduMap.MAP_TYPE_NORMAL) {
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
mToggleMapTypeButton.setText("普通地图");
} else {
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
mToggleMapTypeButton.setText("卫星地图");
}
});
// 检查定位权限
if (hasLocationPermission()) {
enableMyLocation(); // 定位权限已授予
} else {
// 请求定位必需权限
requestLocationPermissions();
}
}
// 初始化步行导航
private void initWalkNavigation() {
// 获取步行导航控制类
mWalkHelper = WalkNavigateHelper.getInstance();
// 初始化引擎
mWalkHelper.initNaviEngine(this, new IWEngineInitListener() {
@Override
public void onEngineInitSuccess() {
Log.d("Navigation", "步行导航引擎初始化成功");
}
@Override
public void onEngineInitFailed(int errorCode) {
Log.e("Navigation", "步行导航引擎初始化失败: " + errorCode);
}
});
}
// 启动步行导航
private void startWalkNavigation(LatLng targetLocation) {
if (mCurrentLocation == null) {
Toast.makeText(this, "无法获取当前位置,导航失败", Toast.LENGTH_SHORT).show();
return;
}
// 构建导航参数
mWalkParam = new WalkNaviLaunchParam();
mWalkParam.startPoint(new WalkRouteNodeInfo().location(mCurrentLocation))
.endPoint(new WalkRouteNodeInfo().location(targetLocation));
// 开始步行导航
try {
mWalkHelper.openWalkNaviActivity(this, mWalkParam);
} catch (Exception e) {
Log.e("Navigation", "启动步行导航失败", e);
Toast.makeText(this, "启动步行导航失败", Toast.LENGTH_SHORT).show();
}
}
// 请求定位权限
private void requestLocationPermissions() {
ActivityCompat.requestPermissions(this, LOCATION_PERMISSIONS, PERMISSION_REQUEST_CODE);
}
// 检查是否具有定位权限
private boolean hasLocationPermission() {
for (String permission : LOCATION_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
// 启用我的位置
private void enableMyLocation() {
try {
LocationClient.setAgreePrivacy(true);
mLocationClient = new LocationClient(getApplicationContext());
mLocationClient.setLocOption(getDefaultLocationClientOption());
mLocationClient.registerLocationListener(new BDAbstractLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null || mBaiduMap == null) {
return;
}
// 更新当前位置
mCurrentLocation = new LatLng(location.getLatitude(), location.getLongitude());
// 显示我的位置
MyLocationData locData = new MyLocationData.Builder()
.latitude(location.getLatitude())
.longitude(location.getLongitude())
.build();
mBaiduMap.setMyLocationData(locData);
// 首次接收到位置信息时移动地图到当前位置
if (!isFirstLocationReceived) {
isFirstLocationReceived = true;
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mCurrentLocation);
mBaiduMap.animateMapStatus(u);
}
}
});
mLocationClient.start();
} catch (Exception e) {
Log.e("MainActivity", "初始化定位客户端失败", e);
Toast.makeText(this, "定位功能初始化失败,请重启应用", Toast.LENGTH_SHORT).show();
}
}
// 获取默认的定位参数
private LocationClientOption getDefaultLocationClientOption() {
LocationClientOption option = new LocationClientOption();
try {
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
option.setCoorType("bd09ll");
option.setScanSpan(1000);
option.setIsNeedAddress(true);
option.setOpenGps(true);
option.setLocationNotify(true);
option.setIsNeedLocationDescribe(true);
option.setIsNeedLocationPoiList(true);
option.setIgnoreKillProcess(false);
option.SetIgnoreCacheException(false);
option.setWifiCacheTimeOut(5 * 60 * 1000);
option.setEnableSimulateGps(false);
} catch (Exception e) {
Log.e("MainActivity", "设置定位参数失败", e);
// 使用默认配置继续执行
}
return option;
}
// 创建选项菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.map_menu, menu);
return true;
}
// 菜单项选择处理
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (mBaiduMap == null) return false;
if (id == R.id.menu_normal_map) {
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
Toast.makeText(this, "已切换到普通地图", Toast.LENGTH_SHORT).show();
return true;
} else if (id == R.id.menu_satellite_map) {
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
Toast.makeText(this, "已切换到卫星地图", Toast.LENGTH_SHORT).show();
return true;
} else if (id == R.id.menu_traffic) {
boolean isTrafficEnabled = !mBaiduMap.isTrafficEnabled();
mBaiduMap.setTrafficEnabled(isTrafficEnabled);
Toast.makeText(this, isTrafficEnabled ? "实时路况已开启" : "实时路况已关闭",
Toast.LENGTH_SHORT).show();
return true;
} else if (id == R.id.menu_location) {
if (mLocationClient != null && mLocationClient.isStarted()) {
// 手动触发一次定位
mLocationClient.requestLocation();
Toast.makeText(this, "正在定位...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "定位服务未启动", Toast.LENGTH_SHORT).show();
}
return true;
}
return super.onOptionsItemSelected(item);
}
// 设置地图中心点的方法
private void setMapCenter(LatLng point, float zoomLevel) {
if (mBaiduMap != null) {
MapStatusUpdate statusUpdate = MapStatusUpdateFactory.newLatLngZoom(point, zoomLevel);
mBaiduMap.setMapStatus(statusUpdate);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
// 检查是否授予了至少一个定位权限
boolean locationGranted = false;
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION) ||
permissions[i].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
locationGranted = true;
}
}
}
if (locationGranted) {
enableMyLocation();
} else {
Toast.makeText(this, "定位权限未授权,定位功能不可用", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onResume() {
super.onResume();
if (mMapView != null) {
mMapView.onResume();
}
// 启动定位
if (mLocationClient != null && !mLocationClient.isStarted()) {
mLocationClient.start();
}
}
@Override
protected void onPause() {
super.onPause();
if (mMapView != null) {
mMapView.onPause();
}
// 停止定位
if (mLocationClient != null && mLocationClient.isStarted()) {
mLocationClient.stop();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放地图资源
if (mMapView != null) {
mMapView.onDestroy();
mMapView = null;
}
// 释放定位资源
if (mBaiduMap != null) {
mBaiduMap.setMyLocationEnabled(false);
mBaiduMap = null;
}
if (mLocationClient != null) {
mLocationClient.stop();
mLocationClient = null;
}
// 释放步行导航资源
if (mWalkHelper != null) {
mWalkHelper.quit();
}
}
}错误指正
最新发布