package com.example.test1;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
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.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private MapView mMapView;
private BaiduMap mBaiduMap;
// 定位相关变量
private LocationClient mLocationClient;
private TextView tvLocationInfo;
private Button btnLocation;
private boolean isFirstLoc = true;
// 权限请求码
private static final int PERMISSION_REQUEST_CODE = 100;
// 必需的权限(添加必要的网络权限)
private String[] neededPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.INTERNET
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate started");
try {
// 设置隐私协议
setAgreePrivacy();
// 初始化百度地图SDK
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
// 初始化视图
initViews();
// 初始化地图
initMap();
// 检查并请求权限
checkAndRequestPermissions();
} catch (Exception e) {
Log.e(TAG, "Error in onCreate: " + e.getMessage(), e);
Toast.makeText(this, "初始化失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void setAgreePrivacy() {
try {
SDKInitializer.setAgreePrivacy(getApplicationContext(), true);
com.baidu.location.LocationClient.setAgreePrivacy(true);
Log.d(TAG, "Privacy policy agreed");
} catch (Exception e) {
Log.e(TAG, "Error setting privacy policy: " + e.getMessage(), e);
}
}
private void initViews() {
try {
mMapView = findViewById(R.id.bmapView);
tvLocationInfo = findViewById(R.id.tv_location_info);
btnLocation = findViewById(R.id.btn_location);
if (mMapView == null) {
Log.e(TAG, "MapView is null!");
return;
}
mBaiduMap = mMapView.getMap();
// 设置定位按钮点击事件
btnLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startLocation();
}
});
Log.d(TAG, "Views initialized");
} catch (Exception e) {
Log.e(TAG, "Error in initViews: " + e.getMessage(), e);
}
}
private void initMap() {
try {
if (mBaiduMap == null) {
Log.e(TAG, "BaiduMap is null in initMap");
return;
}
// 设置地图类型
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
// 开启地图的定位图层
mBaiduMap.setMyLocationEnabled(true);
// 设置初始中心点(北京)
LatLng center = new LatLng(39.915, 116.404);
MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(center);
mBaiduMap.setMapStatus(status);
// 设置缩放级别
MapStatusUpdate zoom = MapStatusUpdateFactory.zoomTo(15.0f);
mBaiduMap.setMapStatus(zoom);
Log.d(TAG, "Map initialized successfully");
} catch (Exception e) {
Log.e(TAG, "Error in initMap: " + e.getMessage(), e);
}
}
private void initLocation() {
try {
if (mLocationClient != null) {
return;
}
// 定位初始化
mLocationClient = new LocationClient(getApplicationContext());
// 设置定位参数 - 修复配置
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
option.setCoorType("bd09ll");
option.setIsNeedAddress(true);
option.setOpenGps(true);
option.setScanSpan(2000); // 改为2秒间隔
option.setLocationNotify(true);
// 添加超时设置
option.setTimeOut(30000);
// 禁用POI列表获取,减少崩溃风险
option.setIsNeedLocationPoiList(false);
mLocationClient.setLocOption(option);
// 注册定位监听器
mLocationClient.registerLocationListener(new MyLocationListener());
Log.d(TAG, "Location initialized successfully");
} catch (Exception e) {
Log.e(TAG, "Error in initLocation: " + e.getMessage(), e);
Toast.makeText(this, "定位初始化失败", Toast.LENGTH_SHORT).show();
}
}
private void startLocation() {
try {
if (!checkLocationPermission()) {
Toast.makeText(this, "请先授予定位权限", Toast.LENGTH_SHORT).show();
checkAndRequestPermissions();
return;
}
if (mLocationClient == null) {
initLocation();
}
if (mLocationClient != null) {
if (mLocationClient.isStarted()) {
mLocationClient.stop();
}
mLocationClient.start();
// 等待一下再请求定位
mLocationClient.requestLocation();
tvLocationInfo.setVisibility(View.VISIBLE);
tvLocationInfo.setText("正在定位中...");
Toast.makeText(this, "开始定位", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Location started");
}
} catch (Exception e) {
Log.e(TAG, "Error in startLocation: " + e.getMessage(), e);
Toast.makeText(this, "定位启动失败", Toast.LENGTH_SHORT).show();
}
}
/**
* 检查并请求所有需要的权限
*/
private void checkAndRequestPermissions() {
List<String> permissionsNeeded = new ArrayList<>();
for (String permission : neededPermissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(permission);
}
}
if (permissionsNeeded.isEmpty()) {
// 所有权限都已授予,初始化定位并自动开始
initLocation();
// 延迟一下再开始定位,确保初始化完成
new android.os.Handler().postDelayed(new Runnable() {
@Override
public void run() {
startLocation();
}
}, 1000);
} else {
// 请求缺少的权限
ActivityCompat.requestPermissions(this,
permissionsNeeded.toArray(new String[0]),
PERMISSION_REQUEST_CODE);
}
}
/**
* 专门检查定位权限
*/
private boolean checkLocationPermission() {
boolean fineLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
boolean coarseLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
return fineLocation || coarseLocation;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
boolean locationPermissionGranted = false;
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int result = grantResults[i];
if ((permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) ||
permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) &&
result == PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
}
}
if (locationPermissionGranted) {
// 定位权限已授予,初始化定位并自动开始
initLocation();
// 延迟开始定位
new android.os.Handler().postDelayed(new Runnable() {
@Override
public void run() {
startLocation();
}
}, 1000);
Toast.makeText(this, "权限获取成功,开始自动定位", Toast.LENGTH_SHORT).show();
} else {
// 定位权限被拒绝
if (tvLocationInfo != null) {
tvLocationInfo.setText("权限被拒绝,无法定位");
tvLocationInfo.setVisibility(View.VISIBLE);
}
Toast.makeText(this, "定位权限被拒绝", Toast.LENGTH_LONG).show();
}
}
}
/**
* 定位监听器 - 添加空值检查
*/
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null || mMapView == null || mBaiduMap == null) {
Log.e(TAG, "Location, MapView or BaiduMap is null");
return;
}
try {
Log.d(TAG, "Location received - Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude()
+ ", Type: " + location.getLocType());
// 检查定位是否有效
if (location.getLocType() == BDLocation.TypeServerError ||
location.getLocType() == BDLocation.TypeNetWorkException ||
location.getLocType() == BDLocation.TypeCriteriaException) {
runOnUiThread(() -> {
if (tvLocationInfo != null) {
tvLocationInfo.setText("定位失败: " + location.getLocTypeDescription());
}
});
return;
}
// 检查坐标是否有效
if (!isValidLocation(location.getLatitude(), location.getLongitude())) {
Log.e(TAG, "Invalid location coordinates");
runOnUiThread(() -> {
if (tvLocationInfo != null) {
tvLocationInfo.setText("获取到无效的定位坐标");
}
});
return;
}
// 更新UI显示定位信息
updateLocationInfo(location);
// 在地图上显示位置
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
.direction(location.getDirection())
.latitude(location.getLatitude())
.longitude(location.getLongitude())
.build();
mBaiduMap.setMyLocationData(locData);
// 如果是第一次定位,移动到当前位置
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
MapStatusUpdate zoom = MapStatusUpdateFactory.zoomTo(18.0f);
mBaiduMap.animateMapStatus(zoom);
}
} catch (Exception e) {
Log.e(TAG, "Error in onReceiveLocation: " + e.getMessage(), e);
}
}
}
/**
* 检查坐标是否有效
*/
private boolean isValidLocation(double lat, double lng) {
return !Double.isNaN(lat) && !Double.isNaN(lng) &&
!Double.isInfinite(lat) && !Double.isInfinite(lng) &&
Math.abs(lat) > 0.001 && Math.abs(lng) > 0.001 &&
Math.abs(lat) < 90 && Math.abs(lng) < 180;
}
private void updateLocationInfo(BDLocation location) {
if (tvLocationInfo == null) return;
StringBuilder sb = new StringBuilder();
sb.append("定位成功:\n");
sb.append("经度: ").append(String.format("%.6f", location.getLongitude())).append("\n");
sb.append("纬度: ").append(String.format("%.6f", location.getLatitude())).append("\n");
sb.append("精度: ").append(String.format("%.1f", location.getRadius())).append("米\n");
if (location.getAddrStr() != null) {
sb.append("地址: ").append(location.getAddrStr());
}
final String locationText = sb.toString();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (tvLocationInfo != null) {
tvLocationInfo.setText(locationText);
}
}
});
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
try {
if (mMapView != null) {
mMapView.onResume();
}
} catch (Exception e) {
Log.e(TAG, "Error in onResume: " + e.getMessage(), e);
}
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
try {
if (mMapView != null) {
mMapView.onPause();
}
// 停止定位以节省电量
if (mLocationClient != null && mLocationClient.isStarted()) {
mLocationClient.stop();
}
} catch (Exception e) {
Log.e(TAG, "Error in onPause: " + e.getMessage(), e);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
try {
// 停止定位
if (mLocationClient != null) {
if (mLocationClient.isStarted()) {
mLocationClient.stop();
}
mLocationClient = null;
}
// 关闭定位图层
if (mBaiduMap != null) {
mBaiduMap.setMyLocationEnabled(false);
}
// 释放地图资源
if (mMapView != null) {
mMapView.onDestroy();
}
} catch (Exception e) {
Log.e(TAG, "Error in onDestroy: " + e.getMessage(), e);
}
}
}怎么修改上述问题
最新发布