融云&高德地图-实现地理位置发送
来源:互联网 发布:视频压缩的常用算法 编辑:程序博客网 时间:2024/05/16 04:47
效果预览
Send:
Click LocationMessage:
实现
1:注册高德地图开发者账号,创建应用、获取高德地图的 appkey
2: jar 包建议直接从 融云 demo 中拷贝。因为某地图厂商的版本兼容做的不好。可能你下载的新版本的 jar. 在老版本的实现代码中就找不到这个接口。或者那个接口变动了
3: 参考 demo 代码 在 RongCloudEvent.java 上实现了 地理位置提供者接口 。 onStartLocation 方法中点击开启 地图的 Activity
@Override public void onStartLocation(Context context, LocationCallback locationCallback) { /** * demo 代码 开发者需替换成自己的代码。 */ DemoContext.getInstance().setLastLocationCallback(locationCallback); Intent intent = new Intent(context, AMAPLocationActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);
AMAPLocationActivity 为核心逻辑类。高德地图的展示 获取经纬度和定位的逻辑全在此处
code:
public class AMAPLocationActivity extends ActionBarActivity implements View.OnClickListener, LocationSource, GeocodeSearch.OnGeocodeSearchListener, AMapLocationListener, AMap.OnCameraChangeListener { private MapView mapView; private AMap aMap; private LocationManagerProxy mLocationManagerProxy; private Handler handler = new Handler(); private LocationSource.OnLocationChangedListener listener; private LatLng myLocation = null; private Marker centerMarker; private boolean isMovingMarker = false; private BitmapDescriptor successDescripter; private GeocodeSearch geocodeSearch; private LocationMessage mMsg; private TextView tvCurLocation; private boolean model = false; private boolean isPerview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_amap); getSupportActionBar().setTitle("地理位置"); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeAsUpIndicator(R.drawable.de_actionbar_back); mapView = (MapView) findViewById(R.id.map); mapView.onCreate(savedInstanceState); initUI(); initAmap(); setUpLocationStyle(); } private void initAmap() { if (aMap == null) { aMap = mapView.getMap(); } if (getIntent().hasExtra("location")) { isPerview = true; mMsg = getIntent().getParcelableExtra("location"); tvCurLocation.setVisibility(View.GONE); returns.setVisibility(View.GONE); if (model) { CameraPosition location = new CameraPosition.Builder() .target(new LatLng(mMsg.getLat(), mMsg.getLng())).zoom(18).bearing(0).tilt(30).build(); show(location); } else { aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f) .position(new LatLng(mMsg.getLat(), mMsg.getLng())).title(mMsg.getPoi()) .snippet(mMsg.getLat() + "," + mMsg.getLng()).draggable(false)); } return; } aMap.setLocationSource(this);// 设置定位监听 aMap.setMyLocationEnabled(true); aMap.getUiSettings().setZoomControlsEnabled(false); aMap.getUiSettings().setMyLocationButtonEnabled(false); CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(15);//设置缩放监听 aMap.moveCamera(cameraUpdate); successDescripter = BitmapDescriptorFactory.fromResource(R.drawable.icon_usecarnow_position_succeed); geocodeSearch = new GeocodeSearch(this); geocodeSearch.setOnGeocodeSearchListener(this); } private static final String MAP_FRAGMENT_TAG = "map"; private SupportMapFragment aMapFragment; private void show(CameraPosition location) { AMapOptions aOptions = new AMapOptions(); aOptions.zoomGesturesEnabled(true); aOptions.scrollGesturesEnabled(false); aOptions.camera(location); if (aMapFragment == null) { aMapFragment = SupportMapFragment.newInstance(aOptions); FragmentTransaction fragmentTransaction = getSupportFragmentManager() .beginTransaction(); fragmentTransaction.add(android.R.id.content, aMapFragment, MAP_FRAGMENT_TAG); fragmentTransaction.commit(); } } private ImageView returns; private void initUI() { returns = (ImageView) findViewById(R.id.myLocation); returns.setOnClickListener(this); tvCurLocation = (TextView) findViewById(R.id.location); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.myLocation: CameraUpdate update = CameraUpdateFactory.changeLatLng(myLocation); aMap.animateCamera(update); break; default: break; } } @Override public void activate(OnLocationChangedListener onLocationChangedListener) { listener = onLocationChangedListener; mLocationManagerProxy = LocationManagerProxy.getInstance(this); mLocationManagerProxy.requestLocationData( LocationProviderProxy.AMapNetwork, -1, 100, this); } @Override public void deactivate() { if (mLocationManagerProxy != null) { mLocationManagerProxy.removeUpdates(this); mLocationManagerProxy.destroy(); } mLocationManagerProxy = null; } @Override public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) { if (i == 0) { if (regeocodeResult != null && regeocodeResult.getRegeocodeAddress() != null) { endAnim(); centerMarker.setIcon(successDescripter); RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress(); String formatAddress = regeocodeResult.getRegeocodeAddress().getFormatAddress(); String shortAdd = formatAddress.replace(regeocodeAddress.getProvince(), "").replace(regeocodeAddress.getCity(), "").replace(regeocodeAddress.getDistrict(), ""); tvCurLocation.setText(shortAdd); double latitude = regeocodeResult.getRegeocodeQuery().getPoint().getLatitude(); double longitude = regeocodeResult.getRegeocodeQuery().getPoint().getLongitude(); mMsg = LocationMessage.obtain(latitude, longitude, shortAdd, getMapUrl(latitude, longitude)); NLog.e("LocationChange", shortAdd + latitude + "----" + longitude); } else { NToast.shortToast(AMAPLocationActivity.this, "没有搜索到结果"); } } else { NToast.shortToast(AMAPLocationActivity.this, "搜索失败,请检查网络"); } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) { } @Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null && aMapLocation.getAMapException().getErrorCode() == 0) { if (listener != null) { listener.onLocationChanged(aMapLocation);// 显示系统小蓝点 } myLocation = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());//获取当前位置经纬度 tvCurLocation.setText(aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName());//当前位置信息 double latitude = aMapLocation.getLatitude(); double longitude = aMapLocation.getLongitude(); mMsg = LocationMessage.obtain(latitude, longitude, aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName(), getMapUrl(latitude, longitude)); NLog.e("LocationInit", aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName() + latitude + "----" + longitude); addChooseMarker(); } } private void addChooseMarker() { //加入自定义标签 MarkerOptions centerMarkerOption = new MarkerOptions().position(myLocation).icon(successDescripter); centerMarker = aMap.addMarker(centerMarkerOption); centerMarker.setPositionByPixels(mapView.getWidth() / 2, mapView.getHeight() / 2); handler.postDelayed(new Runnable() { @Override public void run() { CameraUpdate update = CameraUpdateFactory.zoomTo(17f); aMap.animateCamera(update, 1000, new AMap.CancelableCallback() { @Override public void onFinish() { aMap.setOnCameraChangeListener(AMAPLocationActivity.this); } @Override public void onCancel() { } }); } }, 1000); } private void setMovingMarker() { if (isMovingMarker) return; isMovingMarker = true; centerMarker.setIcon(successDescripter); hideLocationView(); } @Override public void onCameraChange(CameraPosition cameraPosition) { if (centerMarker != null) { setMovingMarker(); } } @Override public void onCameraChangeFinish(CameraPosition cameraPosition) { LatLonPoint point = new LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude); RegeocodeQuery query = new RegeocodeQuery(point, 50, GeocodeSearch.AMAP); geocodeSearch.getFromLocationAsyn(query); if (centerMarker != null) { animMarker(); } showLocationView(); } @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); deactivate(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } @Override protected void onDestroy() { mapView.onDestroy(); super.onDestroy(); } private ValueAnimator animator = null; private void animMarker() { isMovingMarker = false; if (animator != null) { animator.start(); return; } animator = ValueAnimator.ofFloat(mapView.getHeight() / 2, mapView.getHeight() / 2 - 30); animator.setInterpolator(new DecelerateInterpolator()); animator.setDuration(150); animator.setRepeatCount(1); animator.setRepeatMode(ValueAnimator.REVERSE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Float value = (Float) animation.getAnimatedValue(); centerMarker.setPositionByPixels(mapView.getWidth() / 2, Math.round(value)); } }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { centerMarker.setIcon(successDescripter); } }); animator.start(); } private void endAnim() { if (animator != null && animator.isRunning()) animator.end(); } private void hideLocationView() { ObjectAnimator animLocation = ObjectAnimator.ofFloat(tvCurLocation, "TranslationY", -tvCurLocation.getHeight() * 2); animLocation.setDuration(200); animLocation.start(); } private void showLocationView() { ObjectAnimator animLocation = ObjectAnimator.ofFloat(tvCurLocation, "TranslationY", 0); animLocation.setDuration(200); animLocation.start(); } private void setUpLocationStyle() { // 自定义系统定位蓝点 MyLocationStyle myLocationStyle = new MyLocationStyle(); myLocationStyle.myLocationIcon(BitmapDescriptorFactory. fromResource(R.drawable.img_location_now)); myLocationStyle.strokeWidth(0); myLocationStyle.strokeColor(R.color.main_theme_color); myLocationStyle.radiusFillColor(Color.TRANSPARENT); aMap.setMyLocationStyle(myLocationStyle); } private Uri getMapUrl(double x, double y) { String url = "http://restapi.amap.com/v3/staticmap?location=" + y + "," + x + "&zoom=17&scale=2&size=150*150&markers=mid,,A:" + y + "," + x + "&key=" + "ee95e52bf08006f63fd29bcfbcf21df0"; NLog.e("getMapUrl", url); return Uri.parse(url); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.de_location_menu, menu); if (isPerview) { menu.getItem(0).setVisible(false); } return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.send_location: if (mMsg != null) { DemoContext.getInstance().getLastLocationCallback().onSuccess(mMsg); DemoContext.getInstance().setLastLocationCallback(null); finish(); } else { DemoContext.getInstance().getLastLocationCallback() .onFailure("定位失败"); } break; case android.R.id.home: finish(); break; } return super.onOptionsItemSelected(item); }}
xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.amap.api.maps2d.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <TextView android:id="@+id/location" android:text="获取中……" android:drawableLeft="@drawable/schedule_end_icon" android:singleLine="true" android:ellipsize="end" android:padding="10dp" android:background="@drawable/bg_white" android:textColor="@android:color/secondary_text_light" android:textSize="15sp" android:drawablePadding="8dp" android:layout_margin="20dp" android:layout_gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/myLocation" android:src="@drawable/btn_location" android:layout_gravity="right|bottom" android:layout_marginBottom="70dp" android:layout_marginRight="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </FrameLayout></RelativeLayout>
将代码拷贝 和 相关资源文件拷贝以后就能实现。下面对代码逻辑做一下介绍
代码整体分两部分 一部分是发送位置逻辑 一部分是从会话界面地理位置消息点击进来逻辑。主要逻辑是 发送位置逻辑
@Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null && aMapLocation.getAMapException().getErrorCode() == 0) {
如果卡在这个 if 判断没有进来那说明你配置的高德相关的 jar 、key 、storeFile(此处在 gradle 配置) 配置高德环境有问题。此处具体咨询高德地图
另外需要值得注意的一点是获取静态缩略图的问题
private Uri getMapUrl(double x, double y) { String url = "http://restapi.amap.com/v3/staticmap?location=" + y + "," + x + "&zoom=17&scale=2&size=150*150&markers=mid,,A:" + y + "," + x + "&key=" + "ee95e52bf08006f63fd29bcfbcf21df0"; NLog.e("getMapUrl", url); return Uri.parse(url); }
最后组拼的 key.在高德官网解释是说需要配置自己的 高德key.这里是个坑,我拿着自己的 key 去浏览器中解析 返回错误码 10009
当时给愁坏了。后来朋友提示随意拿个别人的 key 绑定了 web api 的去使用试试。结果还真行。所以在此处参考博文的小伙伴直接用上面 demo 提供的 key 即可。
点击地理位置消息预览的逻辑 在 RongCloudEvent.java 重写消息点击事件
if (message.getContent() instanceof LocationMessage) { Intent intent = new Intent(context, AMAPLocationActivity.class); intent.putExtra("location", message.getContent()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); }
在 AMAPLocationActivity 截取并且判断这个 intent
if (getIntent().hasExtra("location")) { isPerview = true; mMsg = getIntent().getParcelableExtra("location"); tvCurLocation.setVisibility(View.GONE); returns.setVisibility(View.GONE); if (model) { CameraPosition location = new CameraPosition.Builder() .target(new LatLng(mMsg.getLat(), mMsg.getLng())).zoom(18).bearing(0).tilt(30).build(); show(location); } else { aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f) .position(new LatLng(mMsg.getLat(), mMsg.getLng())).title(mMsg.getPoi()) .snippet(mMsg.getLat() + "," + mMsg.getLng()).draggable(false)); } return; }
最后的 return 不继续执行代码。完成当前位置的预览即结束
发送地理位置&高德地图结束 有任何疑问可以在下方留言。高德地图相关的问题可登陆高德地图官网进行咨询
- 融云&高德地图-实现地理位置发送
- 融云&百度地图-实现地理位置发送
- 高德地图仿微信实现发送位置
- android 高德地图定位(地理位置) 笔记
- 用java实现地理位置转换,坐标转换,行驶距离计算(高德地图)
- 使用高德地图获取拍照图片地理位置
- 基于百度地图实现融云 sdk 2.8.0+ 发送地理位置
- 高德地图实现仿qq,微信发送位置功能实现逻辑
- 融云,发送位置,腾讯地图改为高德地图,SOSOLocationActivity 核心类修改
- 高德地图-地图选点实现
- 实现高德地图定位
- 高德地图实现定位
- 高德地图实现步骤
- 便捷实现高德地图
- 高德地图小实现
- iOS-高德地图点击地图获取点击点对应的地理位置,并添加自定义的大头针
- 高德获取ip地理位置
- iOS 仿照微信发送地理位置功能 [百度地图]
- cascade.xml参数解析
- 美国残疾人法案
- javascript 面向对象编程(一)
- HDU 3723 Delta Wave
- Julian date(儒略日) java如何做转换
- 融云&高德地图-实现地理位置发送
- java 之匿名内部类
- 主机远程管理工具Xshell 5——(2)使用密钥认证登录
- flume高并发优化——(7)RandomAccessFile升级多文件source
- Python模块常用的几种安装方式
- CSS position 属性
- 浏览器窗口关闭触发的事件
- 项目流程重要性
- 103. Binary Tree Zigzag Level Order Traversal