当前位置: 代码迷 >> Android >> 利用百度mapAndroid sdk高仿微信发送位置功能
  详细解决方案

利用百度mapAndroid sdk高仿微信发送位置功能

热度:16   发布时间:2016-04-28 01:46:08.0
利用百度地图Android sdk高仿微信发送位置功能

接触了百度地图开发平台半个月了,这2天试着模仿了微信给好友发送位置功能,对百度地图的操作能力又上了一个台阶


 

 我在实现这个功能的时候,遇到一些困难,可能也是别人将会遇到的困难,特在此列出


1、在微信发送功能中,不管用户如何拖拽地图,总有个覆盖物固定了MapView中央,怎么实现?

    其实这很容易实现,只要MapView的布局文件中,将一个ImageView覆盖在MapView的中央,就能够实现不管用户如何拖拽地图,覆盖物(ImageView)总固定总MapView中央


2、如何获取MapView中央的地理坐标,也即是屏幕覆盖物处的坐标?

    要获取MapView中央的地理坐标,首先先获取覆盖物在屏幕上的物理坐标,这里得区别一下地理坐标(经纬度)和物理坐标(xy轴);

   可以通过

<mCenterPoint = mBaiduMap.getMapStatus().targetScreen;//mBaiduMap是BaiduMap类的实例
来获取物理坐标,这个物理坐标是不变的,而物理坐标对应的地理坐标却是随着用户拖拽地图而改变,所以,当我们需要地理坐标时,可以通过

currentLatLng = mBaiduMap.getProjection().fromScreenLocation(						mCenterPoint);</strong></span>
获取。


3、如何获取该地理坐标周围的所有poi信息(也就是周围建筑物的信息),而不只是某个类型的兴趣点?

为了实现这个功能,真是费了我好大劲,因为我之前一直以为用POI周边搜索实现的,有人提示我可以通过循环轴线搜索实现不同关键字搜索,但这样子确实很难实现跟微信那样的效果。通过查看API,发现可以通过反地理编码解决这个问题,至于什么事反地理编码,可以到百度地图官网了解,通过调用它,可以返回一个该地理坐标附近建筑信息的一个列表


4、当用户拖拽地图,如何让列表更新到目前中心地理位置的周边信息?

这个困难其实也不难实现,只是重写mBaiduMap.setOnMapTouchListener(touchListener);触摸事件,在触摸监听器的回调函数中

将MapView中央的物理坐标转换成对应的地理坐标,再通过反地理编码获取周边信息,道理同问题3


5、当点击listview某一项时,如何将项地理位置显示在MapView也就是屏幕中央?

很简单,通过listview的适配器获取item的位置信息,包括经纬度,然后用动画跳转到屏幕中央位置即可。


我认为上面5个问题是实现这个功能的关键所在,下面是效果图


上面是一个MapVIew,覆盖物固定在其中央,地图左下角的白色正方形是回到定位点的按钮,因为没找到好看的图片,就留着空白了

下面是一个listView,显示地图指示地点周围的一些位置信息


贴一下实现该功能的核心代码

Activity类

package com.vr.souhuodong.UI.Sou;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Intent;import android.graphics.Point;import android.net.Uri;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;import com.baidu.mapapi.map.BitmapDescriptor;import com.baidu.mapapi.map.BitmapDescriptorFactory;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MarkerOptions;import com.baidu.mapapi.map.MyLocationConfiguration;import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.map.OverlayOptions;import com.baidu.mapapi.model.LatLng;import com.baidu.mapapi.search.core.PoiInfo;import com.baidu.mapapi.search.core.SearchResult;import com.baidu.mapapi.search.geocode.GeoCodeResult;import com.baidu.mapapi.search.geocode.GeoCoder;import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;import com.vr.souhuodong.R;import com.vr.souhuodong.UI.Adapter.PlaceListAdapter;public class ChoosePlaceActivity extends Activity {	MapView mMapView;	BaiduMap mBaiduMap;	ProgressBar mLoadBar;	ImageView mSelectImg;	// 定位	LocationClient mLocationClient = null;	MyBDLocationListner mListner = null;	BitmapDescriptor mCurrentMarker = null;	// 当前经纬度	double mLantitude;	double mLongtitude;	LatLng mLoactionLatLng;	// 设置第一次定位标志	boolean isFirstLoc = true;	// MapView中央对于的屏幕坐标	Point mCenterPoint = null;	// 地理编码	GeoCoder mGeoCoder = null;	// 位置列表	ListView mListView;	PlaceListAdapter mAdapter;	List<PoiInfo> mInfoList;	PoiInfo mCurentInfo;	@Override	protected void onCreate(Bundle savedInstanceState) {		// TODO Auto-generated method stub		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_chooseplace);		initView();	}	/**	 * 初始化界面	 */	private void initView() {		// TODO Auto-generated method stub		// 初始化地图		mMapView = (MapView) findViewById(R.id.chooseplace_bmapView);		mMapView.showZoomControls(false);		mBaiduMap = mMapView.getMap();		MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);		mBaiduMap.setMapStatus(msu);		mBaiduMap.setOnMapTouchListener(touchListener);		// 初始化POI信息列表		mInfoList = new ArrayList<PoiInfo>();		// 初始化当前MapView中心屏幕坐标,初始化当前地理坐标		mCenterPoint = mBaiduMap.getMapStatus().targetScreen;		mLoactionLatLng = mBaiduMap.getMapStatus().target;		// 定位		mBaiduMap.setMyLocationEnabled(true);		mLocationClient = new LocationClient(this);		mListner = new MyBDLocationListner();		mLocationClient.registerLocationListener(mListner);		LocationClientOption option = new LocationClientOption();		option.setOpenGps(true);// 打开gps		option.setCoorType("bd09ll"); // 设置坐标类型		option.setScanSpan(1000);		mLocationClient.setLocOption(option);		mLocationClient.start();		// 地理编码		mGeoCoder = GeoCoder.newInstance();		mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);		// 周边位置列表		mListView = (ListView) findViewById(R.id.place_list);		mLoadBar = (ProgressBar) findViewById(R.id.place_progressBar);		mListView.setOnItemClickListener(itemClickListener);		mAdapter = new PlaceListAdapter(getLayoutInflater(), mInfoList);		mListView.setAdapter(mAdapter);		mSelectImg = new ImageView(this);	}	public void turnBack(View view) {		// 实现动画跳转		MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);		mBaiduMap.animateMapStatus(u);		mBaiduMap.clear();		// 发起反地理编码检索		mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())				.location(mLoactionLatLng));	}	@Override	protected void onDestroy() {		// TODO Auto-generated method stub		super.onDestroy();		mLocationClient.stop();		mGeoCoder.destroy();	}	// 定位监听器	private class MyBDLocationListner implements BDLocationListener {		@Override		public void onReceiveLocation(BDLocation location) {			// TODO Auto-generated method stub			// map view 销毁后不在处理新接收的位置			if (location == null || mMapView == null)				return;			MyLocationData data = new MyLocationData.Builder()//					// .direction(mCurrentX)//					.accuracy(location.getRadius())//					.latitude(location.getLatitude())//					.longitude(location.getLongitude())//					.build();			mBaiduMap.setMyLocationData(data);			// 设置自定义图标			MyLocationConfiguration config = new MyLocationConfiguration(					LocationMode.NORMAL, true, null);			mBaiduMap.setMyLocationConfigeration(config);			mLantitude = location.getLatitude();			mLongtitude = location.getLongitude();			LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);			mLoactionLatLng = new LatLng(mLantitude, mLongtitude);			// 是否第一次定位			if (isFirstLoc) {				isFirstLoc = false;				// 实现动画跳转				MapStatusUpdate u = MapStatusUpdateFactory						.newLatLng(currentLatLng);				mBaiduMap.animateMapStatus(u);				mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())						.location(currentLatLng));				return;			}		}	}	// 地理编码监听器	OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() {		public void onGetGeoCodeResult(GeoCodeResult result) {			if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {				// 没有检索到结果			}			// 获取地理编码结果		}		@Override		public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {			if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {				// 没有找到检索结果			}			// 获取反向地理编码结果			else {				// 当前位置信息				mCurentInfo = new PoiInfo();				mCurentInfo.address = result.getAddress();				mCurentInfo.location = result.getLocation();				mCurentInfo.name = "[位置]";				mInfoList.clear();				mInfoList.add(mCurentInfo);				// 将周边信息加入表				if (result.getPoiList() != null) {					mInfoList.addAll(result.getPoiList());				}				// 通知适配数据已改变				mAdapter.notifyDataSetChanged();				mLoadBar.setVisibility(View.GONE);			}		}	};	// 地图触摸事件监听器	OnMapTouchListener touchListener = new OnMapTouchListener() {		@Override		public void onTouch(MotionEvent event) {			// TODO Auto-generated method stub			if (event.getAction() == MotionEvent.ACTION_UP) {				if (mCenterPoint == null) {					return;				}				// 获取当前MapView中心屏幕坐标对应的地理坐标				LatLng currentLatLng;				currentLatLng = mBaiduMap.getProjection().fromScreenLocation(						mCenterPoint);				System.out.println("----" + mCenterPoint.x);				System.out.println("----" + currentLatLng.latitude);				// 发起反地理编码检索				mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())						.location(currentLatLng));				mLoadBar.setVisibility(View.VISIBLE);			}		}	};	// listView选项点击事件监听器	OnItemClickListener itemClickListener = new OnItemClickListener() {		@Override		public void onItemClick(AdapterView<?> parent, View view, int position,				long id) {			// TODO Auto-generated method stub			// 通知是适配器第position个item被选择了			mAdapter.setNotifyTip(position);			BitmapDescriptor mSelectIco = BitmapDescriptorFactory					.fromResource(R.drawable.icon_geo);			mBaiduMap.clear();			PoiInfo info = (PoiInfo) mAdapter.getItem(position);			LatLng la = info.location;			// 动画跳转			MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);			mBaiduMap.animateMapStatus(u);			// 添加覆盖物			OverlayOptions ooA = new MarkerOptions().position(la)					.icon(mSelectIco).anchor(0.5f, 0.5f);			mBaiduMap.addOverlay(ooA);			// 选中项打勾			mSelectImg.setBackgroundResource(R.drawable.greywhite);			mSelectImg = (ImageView) view.findViewById(R.id.place_select);			mSelectImg.setBackgroundResource(R.drawable.ic_select);			//			Uri mUri = Uri.parse("geo:39.940409,116.355257");//			Intent mIntent = new Intent(Intent.ACTION_VIEW,mUri);//			startActivity(mIntent);		}	};}


自定义的listView适配器

package com.vr.souhuodong.UI.Adapter;import java.util.List;import android.R.integer;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import com.baidu.mapapi.search.core.PoiInfo;import com.vr.souhuodong.R;public class PlaceListAdapter extends BaseAdapter {		List<PoiInfo> mList;	LayoutInflater mInflater;	int notifyTip ;		private class MyViewHolder {		TextView placeName;		TextView placeAddree;		ImageView placeSelected;	}	public PlaceListAdapter(LayoutInflater mInflater , List<PoiInfo> mList) {		super();		this.mList = mList;		this.mInflater = mInflater;		notifyTip = -1 ;	}			/**	 * 设置第几个item被选择	 * @param notifyTip	 */	public void setNotifyTip(int notifyTip) {		this.notifyTip = notifyTip;	}		@Override	public int getCount() {		// TODO Auto-generated method stub		return mList.size();	}	@Override	public Object getItem(int position) {		// TODO Auto-generated method stub		return mList.get(position);	}	@Override	public long getItemId(int position) {		// TODO Auto-generated method stub		return position;	}	@Override	public View getView(int position, View convertView, ViewGroup parent) {		// TODO Auto-generated method stub		MyViewHolder holder;		if (convertView == null) {			System.out.println("----aa-");			convertView = mInflater.inflate(com.vr.souhuodong.R.layout.listitem_place, parent, false);				    holder = new MyViewHolder();			holder.placeName = (TextView) convertView					.findViewById(com.vr.souhuodong.R.id.place_name);			holder.placeAddree = (TextView) convertView					.findViewById(com.vr.souhuodong.R.id.place_adress);			holder.placeSelected = (ImageView) convertView					.findViewById(com.vr.souhuodong.R.id.place_select);			holder.placeName.setText(mList.get(position).name);			holder.placeAddree.setText(mList.get(position).address);			holder.placeSelected.setBackgroundResource(R.drawable.greywhite);			convertView.setTag(holder);		} else {			holder = (MyViewHolder) convertView.getTag();					}		holder.placeName.setText(mList.get(position).name);		holder.placeAddree.setText(mList.get(position).address);		//根据重新加载的时候第position条item是否是当前所选择的,选择加载不同的图片		if(notifyTip == position ){						holder.placeSelected.setBackgroundResource(R.drawable.ic_select);		}					else {			holder.placeSelected.setBackgroundResource(R.drawable.greywhite);		}		return convertView;	}		//	class MyItemClickListener implements OnClickListener {////		ImageView mImg;//		public MyItemClickListener(ImageView mImg) {//			this.mImg = mImg; //		}//		@Override//		public void onClick(View v) {//			// TODO Auto-generated method stub//			mImg.setBackgroundResource(R.drawable.ic_select);//		}//		//	}	}

莫智勋出品


  相关解决方案