package com.netease.nim.demo.location.activity; import android.content.Context; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.AMap.OnCameraChangeListener; import com.amap.api.maps2d.AMapUtils; import com.amap.api.maps2d.CameraUpdate; import com.amap.api.maps2d.CameraUpdateFactory; import com.amap.api.maps2d.MapView; import com.amap.api.maps2d.UiSettings; import com.amap.api.maps2d.model.CameraPosition; import com.amap.api.maps2d.model.LatLng; import com.netease.nim.demo.R; import com.netease.nim.demo.location.helper.NimGeocoder; import com.netease.nim.demo.location.helper.NimLocationManager; import com.netease.nim.demo.location.helper.NimLocationManager.NimLocationListener; import com.netease.nim.demo.location.model.NimLocation; import com.netease.nim.uikit.LocationProvider; import com.netease.nim.uikit.common.activity.UI; import com.netease.nim.uikit.model.ToolBarOptions; public class LocationAmapActivity extends UI implements OnCameraChangeListener, OnClickListener , NimLocationListener { // private static final String TAG = "LocationAmapActivity"; private TextView sendButton; private ImageView pinView; private View pinInfoPanel; private TextView pinInfoTextView; private NimLocationManager locationManager = null; private double latitude; // 经度 private double longitude; // 维度 private String addressInfo; // 对应的地址信息 private static LocationProvider.Callback callback; private double cacheLatitude = -1; private double cacheLongitude = -1; private String cacheAddressInfo; private boolean locating = true; // 正在定位的时候不用去查位置 private NimGeocoder geocoder; AMap amap; private MapView mapView; private Button btnMyLocation; public static void start(Context context, LocationProvider.Callback callback) { LocationAmapActivity.callback = callback; context.startActivity(new Intent(context, LocationAmapActivity.class)); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map_view_amap_layout); mapView = (MapView) findViewById(R.id.autonavi_mapView); mapView.onCreate(savedInstanceState);// 此方法必须重写 ToolBarOptions options = new ToolBarOptions(); setToolBar(R.id.toolbar, options); initView(); initAmap(); initLocation(); updateSendStatus(); } private void initView() { sendButton = findView(R.id.action_bar_right_clickable_textview); sendButton.setText(R.string.send); sendButton.setOnClickListener(this); sendButton.setVisibility(View.INVISIBLE); pinView = (ImageView) findViewById(R.id.location_pin); pinInfoPanel = findViewById(R.id.location_info); pinInfoTextView = (TextView) pinInfoPanel.findViewById(R.id.marker_address); pinView.setOnClickListener(this); pinInfoPanel.setOnClickListener(this); btnMyLocation = (Button) findViewById(R.id.my_location); btnMyLocation.setOnClickListener(this); btnMyLocation.setVisibility(View.GONE); } private void initAmap() { try { amap = mapView.getMap(); amap.setOnCameraChangeListener(this); UiSettings uiSettings = amap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false uiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示 } catch (Exception e) { e.printStackTrace(); } } private void initLocation() { locationManager = new NimLocationManager(this, this); Location location = locationManager.getLastKnownLocation(); Intent intent = getIntent(); float zoomLevel = intent.getIntExtra(LocationExtras.ZOOM_LEVEL, LocationExtras.DEFAULT_ZOOM_LEVEL); LatLng latlng = null; if (location == null) { latlng = new LatLng(39.90923, 116.397428); } else { latlng = new LatLng(location.getLatitude(), location.getLongitude()); } CameraUpdate camera = CameraUpdateFactory.newCameraPosition(new CameraPosition(latlng, zoomLevel, 0, 0)); amap.moveCamera(camera); geocoder = new NimGeocoder(this, geocoderListener); } private void updateSendStatus() { if(isFinishing()) { return; } int titleResID = R.string.location_map; if(TextUtils.isEmpty(addressInfo)) { titleResID = R.string.location_loading; sendButton.setVisibility(View.GONE); } else { sendButton.setVisibility(View.VISIBLE); } if(btnMyLocation.getVisibility() == View.VISIBLE || Math.abs(-1 - cacheLatitude) < 0.1f) { setTitle(titleResID); } else { setTitle(R.string.my_location); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } @Override protected void onPause() { super.onPause(); mapView.onPause(); locationManager.deactive(); } @Override protected void onResume() { super.onResume(); mapView.onResume(); locationManager.activate(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (locationManager != null) { locationManager.deactive(); } callback = null; } private String getStaticMapUrl() { StringBuilder urlBuilder = new StringBuilder(LocationExtras.STATIC_MAP_URL_1); urlBuilder.append(latitude); urlBuilder.append(","); urlBuilder.append(longitude); urlBuilder.append(LocationExtras.STATIC_MAP_URL_2); return urlBuilder.toString(); } private void sendLocation() { Intent intent = new Intent(); intent.putExtra(LocationExtras.LATITUDE, latitude); intent.putExtra(LocationExtras.LONGITUDE, longitude); addressInfo = TextUtils.isEmpty(addressInfo) ? getString(R.string.location_address_unkown) : addressInfo; intent.putExtra(LocationExtras.ADDRESS, addressInfo); intent.putExtra(LocationExtras.ZOOM_LEVEL, amap.getCameraPosition().zoom); intent.putExtra(LocationExtras.IMG_URL, getStaticMapUrl()); if (callback != null) { callback.onSuccess(longitude, latitude, addressInfo); } } @Override public void onClick(View v) { switch(v.getId()) { case R.id.action_bar_right_clickable_textview: sendLocation(); finish(); break; case R.id.location_pin: setPinInfoPanel(!isPinInfoPanelShow()); break; case R.id.location_info: pinInfoPanel.setVisibility(View.GONE); break; case R.id.my_location: locationAddressInfo(cacheLatitude, cacheLongitude, cacheAddressInfo); break; } } private void locationAddressInfo(double lat, double lng, String address) { LatLng latlng = new LatLng(lat, lng); CameraUpdate camera = CameraUpdateFactory.newCameraPosition(new CameraPosition(latlng, amap.getCameraPosition().zoom, 0, 0)); amap.moveCamera(camera); addressInfo = address; latitude = lat; longitude = lng; setPinInfoPanel(true); } private boolean isPinInfoPanelShow() { return pinInfoPanel.getVisibility() == View.VISIBLE; } private void setPinInfoPanel(boolean show) { if(show && !TextUtils.isEmpty(addressInfo)) { pinInfoPanel.setVisibility(View.VISIBLE); pinInfoTextView.setText(addressInfo); } else { pinInfoPanel.setVisibility(View.GONE); } updateSendStatus(); } @Override public void onLocationChanged(NimLocation location) { if(location != null && location.hasCoordinates()) { cacheLatitude = location.getLatitude(); cacheLongitude = location.getLongitude(); cacheAddressInfo = location.getAddrStr(); if(locating) { locating = false; locationAddressInfo(cacheLatitude, cacheLongitude, cacheAddressInfo); } } } @Override public void onCameraChange(CameraPosition arg0) {} @Override public void onCameraChangeFinish(CameraPosition cameraPosition) { if (!locating) { queryLatLngAddress(cameraPosition.target); } else { latitude = cameraPosition.target.latitude; longitude = cameraPosition.target.longitude; } updateMyLocationStatus(cameraPosition); } private void updateMyLocationStatus(CameraPosition cameraPosition) { if(Math.abs(-1 - cacheLatitude) < 0.1f) { // 定位失败 return; } LatLng source = new LatLng(cacheLatitude, cacheLongitude); LatLng target = cameraPosition.target; float distance = AMapUtils.calculateLineDistance(source, target); boolean showMyLocation = distance > 50; btnMyLocation.setVisibility(showMyLocation ? View.VISIBLE:View.GONE); updateSendStatus(); } private void queryLatLngAddress(LatLng latlng) { if(!TextUtils.isEmpty(addressInfo) && latlng.latitude == latitude && latlng.longitude == longitude) { return; } Handler handler = getHandler(); handler.removeCallbacks(runable); handler.postDelayed(runable, 20 * 1000);// 20s超时 geocoder.queryAddressNow(latlng.latitude, latlng.longitude); latitude = latlng.latitude; longitude = latlng.longitude; this.addressInfo = null; setPinInfoPanel(false); } private void clearTimeoutHandler() { Handler handler = getHandler(); handler.removeCallbacks(runable); } private NimGeocoder.NimGeocoderListener geocoderListener = new NimGeocoder.NimGeocoderListener() { @Override public void onGeoCoderResult(NimLocation location) { if(latitude == location.getLatitude() && longitude == location.getLongitude()) { // 响应的是当前查询经纬度 if(location.hasAddress()) { LocationAmapActivity.this.addressInfo = location.getFullAddr(); } else { addressInfo = getString(R.string.location_address_unkown); } setPinInfoPanel(true); clearTimeoutHandler(); } } }; private Runnable runable = new Runnable() { @Override public void run() { LocationAmapActivity.this.addressInfo = getString(R.string.location_address_unkown); setPinInfoPanel(true); } }; }