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);
}
};
}