package com.example.sixaunyi; import static androidx.constraintlayout.motion.utils.Oscillator.TAG; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.Manifest; import android.annotation.SuppressLint; import android.content.Intent; import android.graphics.BitmapFactory; import android.nfc.Tag; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; import com.amap.api.maps.AMap; import com.amap.api.maps.AMapUtils; import com.amap.api.maps.LocationSource; import com.amap.api.maps.MapView; import com.amap.api.maps.model.BitmapDescriptorFactory; 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.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.core.PoiItem; import com.amap.api.services.geocoder.GeocodeResult; import com.amap.api.services.geocoder.GeocodeSearch; import com.amap.api.services.geocoder.RegeocodeAddress; import com.amap.api.services.geocoder.RegeocodeQuery; import com.amap.api.services.geocoder.RegeocodeResult; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.List; import pub.devrel.easypermissions.AfterPermissionGranted; import pub.devrel.easypermissions.EasyPermissions; public class MainActivity extends AppCompatActivity implements AMapLocationListener, LocationSource, AMap.OnMapLongClickListener, GeocodeSearch.OnGeocodeSearchListener, AMap.OnMarkerDragListener, AMap.OnMarkerClickListener{ //请求权限码 private static final int REQUEST_PERMISSIONS = 9527; //声明AMapLocationClient类对象 public AMapLocationClient mLocationClient = null; //声明AMapLocationClientOption对象 public AMapLocationClientOption mLocationOption = null; private MapView mapView = null; private String city; private LatLng Current_latlng; //地图控制器*********非常重要!!!!!! private AMap aMap = null; //位置更改监听 private LocationSource.OnLocationChangedListener mListener; //地理编码搜索 private GeocodeSearch geocodeSearch; //解析成功标识码 private static final int PARSE_SUCCESS_CODE = 1000; //POI查询对象 private PoiSearch.Query query; //POI搜索对象 private PoiSearch poiSearch; //城市码 private String cityCode = null; //浮动按钮 private FloatingActionButton fabPOI; //浮动按钮 清空地图标点 private FloatingActionButton ClearMarker_btn; //浮动按钮 更换活动 private FloatingActionButton ChangeAct_btn; //标点列表 private List markerList = new ArrayList<>(); //标识参数类 private MarkerOptions markerOption = new MarkerOptions(); @SuppressLint("MissingInflatedId") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fabPOI = findViewById(R.id.fab_poi); ClearMarker_btn = findViewById(R.id.clearMarker_btn); ChangeAct_btn = findViewById(R.id.change_btn); ChangeAct_btn.show(); //tvContent = findViewById(R.id.tv_content); /*初始化定位,需要在检查版本之前 *因为配置好之后才能启动定位,否则会报错 */ initLocation(); //初始化地图 initMap(savedInstanceState); //检查安卓版本 checkingAndroidVersion(); } /** * 检查Android版本 */ private void checkingAndroidVersion() { //Android6.0及以上先获取权限再定位 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ requestPermission(); } //Android6.0以下直接定位 else { //直接定位 mLocationClient.startLocation(); } } /** * 动态请求权限 */ @AfterPermissionGranted(REQUEST_PERMISSIONS) private void requestPermission() { String[] permissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (EasyPermissions.hasPermissions(this, permissions)) { //有权限 //****** Log.d(TAG, "已获得权限,可以定位啦!"); showMsg("已获得权限,可以定位啦!"); //开始定位 mLocationClient.startLocation(); } else { //false 无权限 EasyPermissions.requestPermissions(this, "需要权限", REQUEST_PERMISSIONS, permissions); } } //提示框显示文本 private void showMsg(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } /** * 请求权限结果 * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //设置请求到的权限结果 EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } /******** 初始化定位 *******/ private void initLocation() { //初始化定位 try { mLocationClient = new AMapLocationClient(getApplicationContext()); } catch (Exception e) { e.printStackTrace(); } if (mLocationClient != null) { //设置定位回调监听 mLocationClient.setLocationListener(this); //初始化AMapLocationClientOption对象 mLocationOption = new AMapLocationClientOption(); //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); //获取最近3s内精度最高的一次定位结果: //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。 mLocationOption.setOnceLocationLatest(true); //设置是否返回地址信息(默认返回地址信息) mLocationOption.setNeedAddress(true); //设置定位请求超时时间,单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。 mLocationOption.setHttpTimeOut(20000); //关闭缓存机制,高精度定位会产生缓存。 mLocationOption.setLocationCacheEnable(false); //给定位客户端对象设置定位参数 mLocationClient.setLocationOption(mLocationOption); } } /** * 初始化地图 * @param savedInstanceState */ private void initMap(Bundle savedInstanceState) { //因为mapView为null,所以要加上这个括号,不可常规的mapView.findViewById mapView = (MapView) findViewById(R.id.map_view); //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图 mapView.onCreate(savedInstanceState); //初始化地图控制器对象 aMap = mapView.getMap(); // 设置定位监听 aMap.setLocationSource(this); // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false aMap.setMyLocationEnabled(true); //设置地图标志点击事件 aMap.setOnMarkerClickListener(this); //设置地图标志拖拽事件 aMap.setOnMarkerDragListener(this); //开启室内地图 //aMap.showIndoorMap(true); //设置地图长按事件 aMap.setOnMapLongClickListener(this); //构造 GeocodeSearch 对象 try { geocodeSearch = new GeocodeSearch(this); } catch (AMapException e) { e.printStackTrace(); } //设置监听 geocodeSearch.setOnGeocodeSearchListener(this); } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener onLocationChangedListener) { mListener = onLocationChangedListener; if (mLocationClient == null) { mLocationClient.startLocation();//启动定位 } } /** * 停止定位 */ @Override public void deactivate() { mListener = null; if (mLocationClient != null) { mLocationClient.stopLocation(); mLocationClient.onDestroy(); } mLocationClient = null; } @Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null) { //定位成功 if (aMapLocation.getErrorCode() == 0) { //地址 String address = aMapLocation.getAddress(); //城市赋值 city = aMapLocation.getCity(); //当前位置经纬度坐标 Current_latlng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()); //获取纬度 double latitude = aMapLocation.getLatitude(); //获取经度 double longitude = aMapLocation.getLongitude(); Log.d("MainActivity", aMapLocation.getCity()); showMsg(address); //停止定位后,本地定位服务并不会被销毁 mLocationClient.stopLocation(); if (mListener != null) { // 显示系统图标 mListener.onLocationChanged(aMapLocation); } //显示浮动按钮 fabPOI.show(); //赋值 cityCode = aMapLocation.getCityCode(); } else { //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。 Log.e("AmapError", "location Error, ErrCode:" + aMapLocation.getErrorCode() + ", errInfo:" + aMapLocation.getErrorInfo()); } } } /***********************Activity相关函数,其中添加了保证mapView与activity同步相关函数******************/ @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图 mapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制 mapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态 mapView.onSaveInstanceState(outState); } @Override protected void onDestroy() { super.onDestroy(); //销毁定位客户端,同时销毁本地定位服务。 if (mLocationClient != null) { mLocationClient.onDestroy(); } //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图 mapView.onDestroy(); } /******************************************************************/ /* * * 长按地图响应函数 * * */ //LatLng 为高德地图包自带的存储坐标对象 @Override public void onMapLongClick(LatLng latLng) { float distance = AMapUtils.calculateLineDistance(Current_latlng,latLng); //showMsg("长按了地图,经度:"+latLng.longitude+",纬度:"+latLng.latitude); showMsg("直线距离:"+distance+"米"); //坐标转地址 latlonToAddress(latLng); //添加标点 addMarker(latLng); } /** * 添加地图标点 * @param latLng */ private void addMarker(LatLng latLng) { //显示浮动按钮 ClearMarker_btn.show(); //添加标点 Marker marker = aMap.addMarker(markerOption .position(latLng) .draggable(true) //标点图标 .icon(BitmapDescriptorFactory. fromBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.img))) //备注 .title("路径点") .snippet("距离:") ); marker.showInfoWindow(); markerList.add(marker); } /** * 清空地图Marker * @param view */ public void clearAllMarker(View view) { if (markerList != null && markerList.size()>0){ for (Marker markerItem : markerList) { markerItem.remove(); } } ClearMarker_btn.hide(); } public void changeAct(View view) { Intent intent = new Intent(MainActivity.this, VideoActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity(intent); } /** * Marker点击事件 * * @param marker * @return */ @Override public boolean onMarkerClick(Marker marker) { Log.d(TAG,"点击了标点"); //显示InfoWindow /* if (!marker.isInfoWindowShown()) { //显示 marker.showInfoWindow(); } else { //隐藏 marker.hideInfoWindow(); } */ return true; } /** * 开始拖动 * @param marker */ @Override public void onMarkerDragStart(Marker marker) { Log.d(TAG,"开始拖动"); } /** * 拖动中 * @param marker */ @Override public void onMarkerDrag(Marker marker) { Log.d(TAG,"拖动中"); } /** * 拖动完成 * @param marker */ @Override public void onMarkerDragEnd(Marker marker) { Log.d(TAG,"拖动完成"); } /* * * 通过坐标获取地址 * * * * * @param latLng */ private void latlonToAddress(LatLng latLng) { //位置点 通过经纬度进行构建 LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude); //逆编码查询 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 20, GeocodeSearch.AMAP); //异步获取地址信息 geocodeSearch.getFromLocationAsyn(query); } /*****************************坐标转地址**************************** * @param regeocodeResult * @param rCode */ @Override public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int rCode) { if(rCode == PARSE_SUCCESS_CODE){ RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress(); //显示解析后的地址 showMsg("地址:"+regeocodeAddress.getFormatAddress()); }else { showMsg("获取地址失败"); } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) { } /* @Override public void onPoiSearched(PoiResult poiResult, int i) { //解析result获取POI信息 //获取POI组数列表 ArrayList poiItems = poiResult.getPois(); for (PoiItem poiItem : poiItems) { Log.d("MainActivity", " Title:" + poiItem.getTitle() + " Snippet:" + poiItem.getSnippet()); } }*/ /* @Override public void (PoiItem poiItem, int i) { }*/ }