来吧,我们先来看一下原版的微信发送位置
嗯,是发送位置,为什么不带发送实时位置,缺个另外一个真机。嗯,买一个16年出的google亲儿子,嗯,信仰充值先想想就好?。?!
接下来,再来看一下自己的程序gif
嗯哼,看完啦。
一、发送位置的需求分析
从原版微信的gif当中,我们看到,大概可以分为这么几个行为
1、进入页面,产生两个标记点,周围地点列表。
两个标记点 一个是固定不变的当前位置的定位圆形标记,一个是可移动的红色标记。并且,会根据当前经纬度改变位置。
地址列表 就是根据当前刚进入页面的经纬度搜索的出来的 附近poi (附近兴趣点)
2、当我们点击周围点的列表,列表更新圆形绿色切换,这点没什么好说,需要注意的是
地图会动态改变位置
可移动的地图上的红色标记处于地图的中心点位置
3、当我们手动拖动地图,这时候两点注意
当手势松开的时候,可移动红色标记移动并且居中
周围poi列表信息更新,而且第一条信息是我们当前屏幕的中心点所获取的地址,这个地址 逆地里编码 得到的,即经纬度转地址
4、点击搜索条关键字,按关键字进行搜索展示列表
第一个poi信息作为默认选择item
如果我们不按下item,直接返回,那么之前页面的信息不变,地址照旧
如果我们按下item,那么该item作为之前页面的poi地址列表第一条item,并且搜索附近的poi信息。(poi即兴趣点)
????????嗯,大概这么就是介么个样子,页面简单,写成文字还是看起来巴拉巴拉一大堆的。我们的demo大概也就是围绕着上面几点展开的。
二、环境说明
当前微信版本:6.3.25
android高德地图版本:
测试机器:菊花荣耀7,Android6.0
IDE: AS
嗯,交代完毕。
三、开码
我们这里涉及到三个Activity,分别是:
JwActivity ? 得到定位,暂且叫做 A页面
ShareLocActivity ? 发送位置页面 暂且叫做 B页面
SeaechTextAddressActivity ?搜索页面 暂且叫做 C页面
1、发送位置,最基本我们需要获得定位
之前弄得工具类,客官您将就着用
/**
* User: LJM
* Date&Time: 2016-08-17 & 22:36
* Describe: 获取经纬度工具类
*
* 需要权限
* ? ?
需要在application 配置的mate-data 和sevice
android:name="com.amap.api.v2.apikey"
android:value="60f458d237f0494627e196293d49db7e"/>
另外,还需要一个key xxx.jks
*
*/publicclassAMapLocUtilsimplementsAMapLocationListener{
privateAMapLocationClient locationClient =null;// 定位privateAMapLocationClientOption locationOption =null;// 定位设置@OverridepublicvoidonLocationChanged(AMapLocation aMapLocation){ ? ? ? ?mLonLatListener.getLonLat(aMapLocation); ? ? ? ?locationClient.stopLocation(); ? ? ? ?locationClient.onDestroy(); ? ? ? ?locationClient =null; ? ? ? ?locationOption =null; ? ?}
privateLonLatListener mLonLatListener;
publicvoidgetLonLat(Context context, LonLatListener lonLatListener){ ? ? ? ?locationClient =newAMapLocationClient(context); ? ? ? ?locationOption =newAMapLocationClientOption(); ? ? ? ?locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);// 设置定位模式为高精度模式locationClient.setLocationListener(this);// 设置定位监听locationOption.setOnceLocation(false);// 单次定位locationOption.setNeedAddress(true);//逆地理编码mLonLatListener = lonLatListener;//接口locationClient.setLocationOption(locationOption);// 设置定位参数locationClient.startLocation();// 启动定位}
publicinterfaceLonLatListener{
voidgetLonLat(AMapLocation aMapLocation); ? ?}}
好啦,调用一下,奔着分享位置的页面去拉
@OverrideprotectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); ? ? ? ?setContentView(R.layout.activity_jw); ? ? ? ?mTvResult = (TextView) findViewById(R.id.mTvResult); ? ? ? ?mTvSendLoc = (TextView) findViewById(R.id.mTvSendLoc); ? ? ? ?mTvSendLoc.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View view){ ? ? ? ? ? ? ? ?Intent openSend =newIntent(JwActivity.this,ShareLocActivity.class); ? ? ? ? ? ? ? ?openSend.putExtra("lon",mLongitude); ? ? ? ? ? ? ? ?openSend.putExtra("lat",mLatitude); ? ? ? ? ? ? ? ?openSend.putExtra("cityCode",cityCode); ? ? ? ? ? ? ? ?startActivity(openSend); ? ? ? ? ? ?} ? ? ? ?});
newAMapLocUtils().getLonLat(this,newAMapLocUtils.LonLatListener() {
@OverridepublicvoidgetLonLat(AMapLocation aMapLocation){ ? ? ? ? ? ? ? ?mTvResult.setText("当前经度"+aMapLocation.getLongitude()+
"\n当前纬度:"+aMapLocation.getLatitude()+
"\n当前城市:"+aMapLocation.getProvince()+aMapLocation.getCity()+ ? ? ? ? ? ? ? ? ? ? ? ?aMapLocation.getAddress()); ? ? ? ? ? ? ? ?mLongitude = aMapLocation.getLongitude(); ? ? ? ? ? ? ? ?mLatitude = aMapLocation.getLatitude(); ? ? ? ? ? ? ? ?cityCode = aMapLocation.getCityCode(); ? ? ? ? ? ? ? ?mTvSendLoc.setVisibility(View.VISIBLE); ? ? ? ? ? ?} ? ? ? ?}); ? ?}
2、 逆地理编码 ?经纬度转地址
从这里开始,我们就跳到了B页面啦~~~
B页面拿到A页面的经纬度之后,就开始心急火燎地想把经纬度转地址啦,这个时候 逆地理编码 出现了。
逆地理编码?大概是这么几步走的
1、得到GeocodeSearch的实例
2、实现GeocodeSearch.OnGeocodeSearchListener接口
3、实现接口就必须实现实现一下两方法 onRegeocodeSearched和onGeocodeSearched。
Geocode是地理编码的意思,Regeocode就是逆地理编码的。
所以我们主要逆地理实现逻辑都在onRegeocodeSearched方法,转成代码大概就是:
step1:
privateGeocodeSearch geocoderSearch;
step2
geocoderSearch =newGeocodeSearch(this);
step3
/**
? ? * 根据经纬度得到地址
? ? */publicvoidgetAddress(finalLatLng latLonPoint){
// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系RegeocodeQuery query =newRegeocodeQuery(convertToLatLonPoint(latLonPoint),200, GeocodeSearch.AMAP); ? ? ? ?geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求}
/**
? ? * 逆地理编码回调
? ? */@OverridepublicvoidonRegeocodeSearched(RegeocodeResult result,intrCode){
if(rCode ==1000) {
if(result !=null&& result.getRegeocodeAddress() !=null&& result.getRegeocodeAddress().getFormatAddress() !=null) { ? ? ? ? ? ? ? ?addressName = result.getRegeocodeAddress().getFormatAddress();// 逆转地里编码不是每次都可以得到对应地图上的opiL.d("逆地理编码回调 ?得到的地址:"+ addressName); ? ? ? ? ? ? ? ?mAddressEntityFirst =newAddressSearchTextEntity(addressName, addressName,true, convertToLatLonPoint(mFinalChoosePosition)); ? ? ? ? ? ?}else{ ? ? ? ? ? ? ? ?ToastUtil.show(ShareLocActivity.this, R.string.no_result); ? ? ? ? ? ?} ? ? ? ?}elseif(rCode ==27){ ? ? ? ? ? ?ToastUtil.show(this, R.string.error_network); ? ? ? ?}elseif(rCode ==32){ ? ? ? ? ? ?ToastUtil.show(this, R.string.error_key); ? ? ? ?}else{ ? ? ? ? ? ?ToastUtil.show(this, ? ? ? ? ? ? ? ? ? ?getString(R.string.error_other) + rCode); ? ? ? ?} ? ?}
/**
? ? * 地理编码查询回调
? ? */@OverridepublicvoidonGeocodeSearched(GeocodeResult result,intrCode){ ? ?}
返回码1000表示转换成功,拿到我们RegeocodeResult的形参我们可以得到地址。
看个大概就行,后面附上这个页面的完整代码。
3、根据经纬度搜索周围poi信息
poi搜索分 搜索关键字 和 搜索经纬度。
官网的demo提供了搜索关键字的,但是没有?相应的按照经纬度的,其实做起来也差不多,但是一开始看文档找呀找找不到,为什么不也示例一下。
其实使用方法也是比较类似的。
1、首先我们要得到private PoiSearch.Query 的实例
2、设置 按需求设置搜索配置
2.1、按经纬度搜索该点周围的poi信息
/**
? ? * 开始进行poi搜索 ? 重点
? ? * 通过经纬度获取附近的poi信息
? ? *
? ? * 1、keyword 传 ""
? ? * 2、poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true)); 根据
? ? */protectedvoiddoSearchQuery(){ ? ? ? ?currentPage =0; ? ? ? ?query =newPoiSearch.Query("","", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)query.setPageSize(20);// 设置每页最多返回多少条poiitemquery.setPageNum(currentPage);// 设置查第一页LatLonPoint lpTemp = convertToLatLonPoint(mFinalChoosePosition);
if(lpTemp !=null) { ? ? ? ? ? ?poiSearch =newPoiSearch(this, query); ? ? ? ? ? ?poiSearch.setOnPoiSearchListener(this);// 实现 ?onPoiSearched ?和 ?onPoiItemSearchedpoiSearch.setBound(newPoiSearch.SearchBound(lpTemp,5000,true));//// 设置搜索区域为以lp点为圆心,其周围5000米范围poiSearch.searchPOIAsyn();// 异步搜索} ? ?}
2.2、按照关键字搜索附近的poi信息
/** ? ? * 按照关键字搜索附近的poi信息 ? ? * @paramkey ? ? */protectedvoiddoSearchQueryWithKeyWord(String key){ ? ? ? ?currentPage =0; ? ? ? ?query =newPoiSearch.Query(key,"", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)query.setPageSize(20);// 设置每页最多返回多少条poiitemquery.setPageNum(currentPage);// 设置查第一页if(lp !=null) { ? ? ? ? ? ?poiSearch =newPoiSearch(this, query); ? ? ? ? ? ?poiSearch.setOnPoiSearchListener(this);// 实现 ?onPoiSearched ?和 ?onPoiItemSearchedpoiSearch.setBound(newPoiSearch.SearchBound(lp,5000,true));//// 设置搜索区域为以lp点为圆心,其周围5000米范围poiSearch.searchPOIAsyn();// 异步搜索} ? ?}
不管是按照关键字还是按照经纬度,我们都要实现利用setOnPoiSearchListener实现搜索poi的接口,然后实现 onPoiSearched 和 onPoiItemSearched这两个方法,在关键onPoiSearched方法里面我们可以得到搜索的poi结果集合。
3、在onPoiSearched方法里面操作数据,更新列表
/** ? ? * poi 附近数据搜索 ? ? * ? ? * @paramresult ? ? * @paramrcode ? ? */@OverridepublicvoidonPoiSearched(PoiResult result,intrcode){
if(rcode ==1000) {
if(result !=null&& result.getQuery() !=null) {// 搜索poi的结果if(result.getQuery().equals(query)) {// 是否是同一条poiResult = result; ? ? ? ? ? ? ? ? ? ?poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始List suggestionCities = poiResult ? ? ? ? ? ? ? ? ? ? ? ? ? ?.getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息mDatas.clear(); ? ? ? ? ? ? ? ? ? ?mDatas.add(mAddressEntityFirst);// 第一个元素AddressSearchTextEntity addressEntity =null;
for(PoiItem poiItem : poiItems) { ? ? ? ? ? ? ? ? ? ? ? ?L.d("得到的数据 poiItem "+ poiItem.getSnippet()); ? ? ? ? ? ? ? ? ? ? ? ?addressEntity =newAddressSearchTextEntity(poiItem.getTitle(), poiItem.getSnippet(),false, poiItem.getLatLonPoint()); ? ? ? ? ? ? ? ? ? ? ? ?mDatas.add(addressEntity); ? ? ? ? ? ? ? ? ? ?}
if(isHandDrag) { ? ? ? ? ? ? ? ? ? ? ? ?mDatas.get(0).isChoose =true; ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?mRvAddressAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ?} ? ? ? ? ? ?}else{ ? ? ? ? ? ? ? ?ToastUtil ? ? ? ? ? ? ? ? ? ? ? ?.show(ShareLocActivity.this,"对不起,没有搜索到相关数据!"); ? ? ? ? ? ?} ? ? ? ?} ? ?}
@OverridepublicvoidonPoiItemSearched(PoiItem poiitem,intrcode){ ? ?}
这么一个流程跑下来,poi数据就拿到了。
4、拖动地图
实现OnCameraChangeListener接口?mAMap.setOnCameraChangeListener(this);
实现 onCameraChange 和 onCameraChangeFinish两个方法
// 拖动地图@OverridepublicvoidonCameraChange(CameraPosition cameraPosition){
//L.d("拖动地图 onCameraChange ");}
/** ? ? * 拖动地图 结束回调 ? ? * ? ? * @paramcameraPosition 当地图位置发生变化,就重新查询数据(手动拖动或者代码改变地图位置都会调用) ? ? */@OverridepublicvoidonCameraChangeFinish(CameraPosition cameraPosition){ ? ? ? ?mFinalChoosePosition = cameraPosition.target; ? ? ? ?L.d("拖动地图 Finish changeCenterMarker 经度"+ mFinalChoosePosition.longitude +" ? 纬度:"+ mFinalChoosePosition.latitude); ? ? ? ?mIvCenter.startAnimation(animationMarker);
if(isHandDrag||isFirstLoadList) {//手动去拖动地图getAddress(cameraPosition.target); ? ? ? ? ? ?doSearchQuery(); ? ? ? ?}elseif(isBackFromSearchChoose){ ? ? ? ? ? ?doSearchQuery(); ? ? ? ?}else{ ? ? ? ? ? ?mRvAddressAdapter.notifyDataSetChanged(); ? ? ? ?} ? ? ? ?isHandDrag =true; ? ? ? ?isFirstLoadList =false; ? ?}
这里需要注意的是,
mAMap.moveCamera方法可以通过代码手动移动地图,他会自动调用onCameraChangeFinish方法(OnCameraChangeListener按道理也是会的)
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng(lp.getLatitude(), lp.getLongitude()),20));
嗯,大概就是这样子了。
至于C页面(就是我们在B页面按下搜索键跳转的页面,他其实也就是关键字搜索而且)
四、完整代码
接下我们看一下完整的B页面和C页面的代码吧,B页面,分享位置页面。
publicclassShareLocActivityextendsCheckPermissionsActivityimplementsView.OnClickListener,
? ? ? ?AMap.OnMapClickListener,
PoiSearch.OnPoiSearchListener,AMap.OnCameraChangeListener,Animation.AnimationListener,GeocodeSearch.OnGeocodeSearchListener
{
privatestaticfinalintOPEN_SEARCH =0X0001;
privateMapView mapview;
privateAMap mAMap;
privatePoiResult poiResult;// poi返回的结果privateintcurrentPage =0;// 当前页面,从0开始计数privatePoiSearch.Query query;// Poi查询条件类privateLatLonPoint lp;//privateMarker locationMarker;// 选择的点privatePoiSearch poiSearch;
privateList poiItems;// poi数据privateRelativeLayout mPoiDetail;
privateTextView mPoiName, mPoiAddress;
privateString keyWord ="";
privateString city;
privateTextView mTvHint;
privateRelativeLayout search_bar_layout;
privateImageView mIvCenter;
privateAnimation animationMarker;
privateLatLng mFinalChoosePosition;//最终选择的点privateGeocodeSearch geocoderSearch;
privateString addressName;
privateRecyclerView mRvAddress;
privateRvAddressSearchTextAdapter mRvAddressAdapter;
privateArrayList mDatas =newArrayList<>();
privateAddressSearchTextEntity mAddressEntityFirst =null;
privateTextView mTvSearch;
privatebooleanisHandDrag =true;
privatebooleanisFirstLoadList =true;
privatebooleanisBackFromSearchChoose =false;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); ? ? ? ?setContentView(R.layout.activity_share_loc); ? ? ? ?Intent intent = getIntent();
doublelon = intent.getDoubleExtra("lon",0);
doublelat = intent.getDoubleExtra("lat",0); ? ? ? ?city = intent.getStringExtra("cityCode"); ? ? ? ?lp =newLatLonPoint(lat, lon); ? ? ? ?mapview = (MapView) findViewById(R.id.mapView); ? ? ? ?mIvCenter = (ImageView) findViewById(R.id.mIvCenter); ? ? ? ?mapview.onCreate(savedInstanceState); ? ? ? ?animationMarker = AnimationUtils.loadAnimation(this, ? ? ? ? ? ? ? ?R.anim.bounce_interpolator); ? ? ? ?mRvAddress = (RecyclerView) findViewById(R.id.mRvAddress); ? ? ? ?LinearLayoutManager layoutManager =newLinearLayoutManager(ShareLocActivity.this); ? ? ? ?layoutManager.setOrientation(LinearLayoutManager.VERTICAL); ? ? ? ?mRvAddress.setLayoutManager(layoutManager); ? ? ? ?mRvAddressAdapter =newRvAddressSearchTextAdapter(ShareLocActivity.this, mDatas); ? ? ? ?mRvAddress.setAdapter(mRvAddressAdapter); ? ? ? ?mRvAddressAdapter.setOnItemClickLitener(newRvAddressSearchTextAdapter.OnItemClickLitener() {
@OverridepublicvoidonItemClick(View view,intposition){ ? ? ? ? ? ? ? ?mFinalChoosePosition = convertToLatLng(mDatas.get(position).latLonPoint);
for(inti =0; i < mDatas.size(); i++) { ? ? ? ? ? ? ? ? ? ?mDatas.get(i).isChoose =false; ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ?mDatas.get(position).isChoose =true; ? ? ? ? ? ? ? ?L.d("点击后的最终经纬度: ?纬度"+ mFinalChoosePosition.latitude +" 经度 "+ mFinalChoosePosition.longitude); ? ? ? ? ? ? ? ?isHandDrag =false;// 点击之后,我利用代码指定的方式改变了地图中心位置,所以也会调用 onCameraChangeFinish// 只要地图发生改变,就会调用 onCameraChangeFinish ,不是说非要手动拖动屏幕才会调用该方法mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng(mFinalChoosePosition.latitude, mFinalChoosePosition.longitude),20)); ? ? ? ? ? ?}
@OverridepublicvoidonItemLongClick(View view,intposition){ ? ? ? ? ? ?} ? ? ? ?}); ? ? ? ?init(); ? ?}
/**
? ? * 初始化AMap对象
? ? */privatevoidinit(){
if(mAMap ==null) { ? ? ? ? ? ?mAMap = mapview.getMap(); ? ? ? ? ? ?mAMap.setOnMapClickListener(this); ? ? ? ? ? ?mAMap.setOnCameraChangeListener(this);// 对amap添加移动地图事件监听器search_bar_layout = (RelativeLayout) findViewById(R.id.search_bar_layout); ? ? ? ? ? ?search_bar_layout.setOnClickListener(this); ? ? ? ? ? ?animationMarker.setAnimationListener(this); ? ? ? ? ? ?locationMarker = mAMap.addMarker(newMarkerOptions() ? ? ? ? ? ? ? ? ? ?.anchor(0.5f,0.5f) ? ? ? ? ? ? ? ? ? ?.icon(BitmapDescriptorFactory ? ? ? ? ? ? ? ? ? ? ? ? ? ?.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.point4))) ? ? ? ? ? ? ? ? ? ?.position(newLatLng(lp.getLatitude(), lp.getLongitude()))); ? ? ? ? ? ?mFinalChoosePosition = locationMarker.getPosition(); ? ? ? ?} ? ? ? ?setup();
// 只要地图发生改变,就会调用 onCameraChangeFinish ,不是说非要手动拖动屏幕才会调用该方法mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng(lp.getLatitude(), lp.getLongitude()),20)); ? ?}
privatevoidsetup(){ ? ? ? ?mPoiDetail = (RelativeLayout) findViewById(R.id.poi_detail); ? ? ? ?mPoiDetail.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View v){ ? ? ? ? ? ?} ? ? ? ?}); ? ? ? ?mPoiName = (TextView) findViewById(R.id.poi_name); ? ? ? ?mPoiAddress = (TextView) findViewById(R.id.poi_address); ? ? ? ?mTvHint = (TextView) findViewById(R.id.mTvHint); ? ? ? ?mTvHint.setOnClickListener(this); ? ? ? ?mTvSearch = (TextView) findViewById(R.id.mTvSearch); ? ? ? ?mTvSearch.setOnClickListener(this); ? ? ? ?geocoderSearch =newGeocodeSearch(this); ? ? ? ?geocoderSearch.setOnGeocodeSearchListener(this); ? ? ? ?mIvCenter.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View view){ ? ? ? ? ? ? ? ?ToastUtil.show(ShareLocActivity.this,"当前选择的经度:"+ mFinalChoosePosition.longitude +" ?纬度:"+ mFinalChoosePosition.latitude); ? ? ? ? ? ?} ? ? ? ?}); ? ?}
// 拖动地图@OverridepublicvoidonCameraChange(CameraPosition cameraPosition){
//L.d("拖动地图 onCameraChange ");}
/** ? ? * 拖动地图 结束回调 ? ? * ? ? * @paramcameraPosition 当地图位置发生变化,就重新查询数据(手动拖动或者代码改变地图位置都会调用) ? ? */@OverridepublicvoidonCameraChangeFinish(CameraPosition cameraPosition){ ? ? ? ?mFinalChoosePosition = cameraPosition.target; ? ? ? ?L.d("拖动地图 Finish changeCenterMarker 经度"+ mFinalChoosePosition.longitude +" ? 纬度:"+ mFinalChoosePosition.latitude); ? ? ? ?mIvCenter.startAnimation(animationMarker);
if(isHandDrag||isFirstLoadList) {//手动去拖动地图getAddress(cameraPosition.target); ? ? ? ? ? ?doSearchQuery(); ? ? ? ?}elseif(isBackFromSearchChoose){ ? ? ? ? ? ?doSearchQuery(); ? ? ? ?}else{ ? ? ? ? ? ?mRvAddressAdapter.notifyDataSetChanged(); ? ? ? ?} ? ? ? ?isHandDrag =true; ? ? ? ?isFirstLoadList =false; ? ?}
// ======== ?poi搜索 周边 ?以下 =====================/**
? ? * 开始进行poi搜索 ? 重点
? ? * 通过经纬度获取附近的poi信息
? ? *
? ? * 1、keyword 传 ""
? ? * 2、poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true)); 根据
? ? */protectedvoiddoSearchQuery(){ ? ? ? ?currentPage =0; ? ? ? ?query =newPoiSearch.Query("","", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)query.setPageSize(20);// 设置每页最多返回多少条poiitemquery.setPageNum(currentPage);// 设置查第一页LatLonPoint lpTemp = convertToLatLonPoint(mFinalChoosePosition);
if(lpTemp !=null) { ? ? ? ? ? ?poiSearch =newPoiSearch(this, query); ? ? ? ? ? ?poiSearch.setOnPoiSearchListener(this);// 实现 ?onPoiSearched ?和 ?onPoiItemSearchedpoiSearch.setBound(newPoiSearch.SearchBound(lpTemp,5000,true));//// 设置搜索区域为以lp点为圆心,其周围5000米范围poiSearch.searchPOIAsyn();// 异步搜索} ? ?}
/** ? ? * poi 附近数据搜索 ? ? * ? ? * @paramresult ? ? * @paramrcode ? ? */@OverridepublicvoidonPoiSearched(PoiResult result,intrcode){
if(rcode ==1000) {
if(result !=null&& result.getQuery() !=null) {// 搜索poi的结果if(result.getQuery().equals(query)) {// 是否是同一条poiResult = result; ? ? ? ? ? ? ? ? ? ?poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始List suggestionCities = poiResult ? ? ? ? ? ? ? ? ? ? ? ? ? ?.getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息mDatas.clear();
//if(isFirstLoadList || isBackFromSearchChoose){mDatas.add(mAddressEntityFirst);// 第一个元素AddressSearchTextEntity addressEntity =null;
for(PoiItem poiItem : poiItems) { ? ? ? ? ? ? ? ? ? ? ? ?L.d("得到的数据 poiItem "+ poiItem.getSnippet()); ? ? ? ? ? ? ? ? ? ? ? ?addressEntity =newAddressSearchTextEntity(poiItem.getTitle(), poiItem.getSnippet(),false, poiItem.getLatLonPoint()); ? ? ? ? ? ? ? ? ? ? ? ?mDatas.add(addressEntity); ? ? ? ? ? ? ? ? ? ?}if(isHandDrag) { ? ? ? ? ? ? ? ? ? ? ? ?mDatas.get(0).isChoose =true; ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?mRvAddressAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ?} ? ? ? ? ? ?}else{ ? ? ? ? ? ? ? ?ToastUtil ? ? ? ? ? ? ? ? ? ? ? ?.show(ShareLocActivity.this,"对不起,没有搜索到相关数据!"); ? ? ? ? ? ?} ? ? ? ?} ? ?}
@OverridepublicvoidonPoiItemSearched(PoiItem poiitem,intrcode){ ? ?}
/** ? ? * 按照关键字搜索附近的poi信息 ? ? * @paramkey ? ? */protectedvoiddoSearchQueryWithKeyWord(String key){ ? ? ? ?currentPage =0; ? ? ? ?query =newPoiSearch.Query(key,"", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)query.setPageSize(20);// 设置每页最多返回多少条poiitemquery.setPageNum(currentPage);// 设置查第一页if(lp !=null) { ? ? ? ? ? ?poiSearch =newPoiSearch(this, query); ? ? ? ? ? ?poiSearch.setOnPoiSearchListener(this);// 实现 ?onPoiSearched ?和 ?onPoiItemSearchedpoiSearch.setBound(newPoiSearch.SearchBound(lp,5000,true));//// 设置搜索区域为以lp点为圆心,其周围5000米范围poiSearch.searchPOIAsyn();// 异步搜索} ? ?}
// ======== ?poi搜索 周边 ?以上 ? =====================/**
? ? * 根据经纬度得到地址
? ? */publicvoidgetAddress(finalLatLng latLonPoint){
// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系RegeocodeQuery query =newRegeocodeQuery(convertToLatLonPoint(latLonPoint),200, GeocodeSearch.AMAP); ? ? ? ?geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求}
/**
? ? * 逆地理编码回调
? ? */@OverridepublicvoidonRegeocodeSearched(RegeocodeResult result,intrCode){
if(rCode ==1000) {
if(result !=null&& result.getRegeocodeAddress() !=null&& result.getRegeocodeAddress().getFormatAddress() !=null) { ? ? ? ? ? ? ? ?addressName = result.getRegeocodeAddress().getFormatAddress();// 逆转地里编码不是每次都可以得到对应地图上的opiL.d("逆地理编码回调 ?得到的地址:"+ addressName); ? ? ? ? ? ? ? ?mAddressEntityFirst =newAddressSearchTextEntity(addressName, addressName,true, convertToLatLonPoint(mFinalChoosePosition)); ? ? ? ? ? ?}else{ ? ? ? ? ? ? ? ?ToastUtil.show(ShareLocActivity.this, R.string.no_result); ? ? ? ? ? ?} ? ? ? ?}elseif(rCode ==27){ ? ? ? ? ? ?ToastUtil.show(this, R.string.error_network); ? ? ? ?}elseif(rCode ==32){ ? ? ? ? ? ?ToastUtil.show(this, R.string.error_key); ? ? ? ?}else{ ? ? ? ? ? ?ToastUtil.show(this, ? ? ? ? ? ? ? ? ? ?getString(R.string.error_other) + rCode); ? ? ? ?} ? ?}
/**
? ? * 地理编码查询回调
? ? */@OverridepublicvoidonGeocodeSearched(GeocodeResult result,intrCode){ ? ?}
/**
? ? * 把LatLonPoint对象转化为LatLon对象
? ? */publicLatLngconvertToLatLng(LatLonPoint latLonPoint){
returnnewLatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude()); ? ?}
/**
? ? * 把LatLng对象转化为LatLonPoint对象
? ? */publicstaticLatLonPointconvertToLatLonPoint(LatLng latlon){
returnnewLatLonPoint(latlon.latitude, latlon.longitude); ? ?}
/**
? ? * 方法必须重写
? ? */@OverrideprotectedvoidonResume(){
super.onResume(); ? ? ? ?mapview.onResume(); ? ? ? ?whetherToShowDetailInfo(false); ? ?}
/**
? ? * 方法必须重写
? ? */@OverrideprotectedvoidonPause(){
super.onPause(); ? ? ? ?mapview.onPause(); ? ?}
/**
? ? * 方法必须重写
? ? */@OverrideprotectedvoidonSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState); ? ? ? ?mapview.onSaveInstanceState(outState); ? ?}
/**
? ? * 方法必须重写
? ? */@OverrideprotectedvoidonDestroy(){
super.onDestroy(); ? ? ? ?mapview.onDestroy(); ? ?}
@OverridepublicvoidonClick(View v){
switch(v.getId()) {
caseR.id.mTvHint:
caseR.id.search_bar_layout: ? ? ? ? ? ? ? ?Intent intent =newIntent(ShareLocActivity.this, SeaechTextAddressActivity.class); ? ? ? ? ? ? ? ?intent.putExtra("point", mFinalChoosePosition); ? ? ? ? ? ? ? ?startActivityForResult(intent, OPEN_SEARCH); ? ? ? ? ? ? ? ?isBackFromSearchChoose =false;
break;
caseR.id.mTvSearch: ? ? ? ? ? ? ? ?AddressSearchTextEntity finalChooseEntity =null;
for(AddressSearchTextEntity searchTextEntity : mDatas) {
if(searchTextEntity.isChoose) { ? ? ? ? ? ? ? ? ? ? ? ?finalChooseEntity = searchTextEntity; ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ?}
if(finalChooseEntity !=null) { ? ? ? ? ? ? ? ? ? ?L.d("最终点击发送到要上一页的数据:"+"\n 经度"+ finalChooseEntity.latLonPoint.getLongitude() ? ? ? ? ? ? ? ? ? ? ? ? ? ?+"\n 纬度"+ finalChooseEntity.latLonPoint.getLatitude() ? ? ? ? ? ? ? ? ? ? ? ? ? ?+"\n 地址"+ finalChooseEntity.mainAddress ? ? ? ? ? ? ? ? ? ?); ? ? ? ? ? ? ? ? ? ?ToastUtil.show(ShareLocActivity.this,"最终点击发送到要上一页的数据:"+"\n 经度"+ finalChooseEntity.latLonPoint.getLongitude() ? ? ? ? ? ? ? ? ? ? ? ? ? ?+"\n 纬度"+ finalChooseEntity.latLonPoint.getLatitude() ? ? ? ? ? ? ? ? ? ? ? ? ? ?+"\n 地址"+ finalChooseEntity.mainAddress); ? ? ? ? ? ? ? ?}
break;
default:
break; ? ? ? ?} ? ?}
privatevoidwhetherToShowDetailInfo(booleanisToShow){
if(isToShow) { ? ? ? ? ? ?mPoiDetail.setVisibility(View.VISIBLE); ? ? ? ?}else{ ? ? ? ? ? ?mPoiDetail.setVisibility(View.GONE); ? ? ? ?} ? ?}
// 单击地图@OverridepublicvoidonMapClick(LatLng latlng){ ? ? ? ?ToastUtil.show(ShareLocActivity.this,"点击地图结果: ?经度:"+ latlng.longitude +" ? 纬度: "+ latlng.latitude); ? ?}
/**
? ? * poi没有搜索到数据,返回一些推荐城市的信息
? ? */privatevoidshowSuggestCity(List cities){ ? ? ? ?String infomation ="推荐城市\n";
for(inti =0; i < cities.size(); i++) { ? ? ? ? ? ?infomation +="城市名称:"+ cities.get(i).getCityName() +"城市区号:"+ cities.get(i).getCityCode() +"城市编码:"+ cities.get(i).getAdCode() +"\n"; ? ? ? ?} ? ? ? ?ToastUtil.show(this, infomation); ? ?}
// 动画复写的三个方法@OverridepublicvoidonAnimationStart(Animation animation){ ? ? ? ?mIvCenter.setImageResource(R.drawable.poi_marker_pressed); ? ?}
@OverridepublicvoidonAnimationRepeat(Animation animation){ ? ?}
@OverridepublicvoidonAnimationEnd(Animation animation){ ? ? ? ?mIvCenter.setImageResource(R.drawable.poi_marker_pressed); ? ?}
@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == OPEN_SEARCH && resultCode == RESULT_OK) { ? ? ? ? ? ?AddressSearchTextEntity backEntity = (AddressSearchTextEntity) data.getParcelableExtra("backEntity"); ? ? ? ? ? ?mAddressEntityFirst = backEntity;// 上一个页面传过来的 item对象mAddressEntityFirst.isChoose =true; ? ? ? ? ? ?isBackFromSearchChoose =true; ? ? ? ? ? ?isHandDrag =false; ? ? ? ? ? ?mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng(backEntity.latLonPoint.getLatitude(), backEntity.latLonPoint.getLongitude()),20)); ? ? ? ?} ? ?}}
嗯??雌鹄闯ち艘坏?,客官如果看到了这里也挺不容易的,就权且当个参考吧。哈哈哈
C页面代码篇幅所限删减,全部内容可点击左下角“阅读原文”查看。
嗯,到这里就差不多了。
其实结合官方demo,折腾起来也就差不多了。
程序有一个小bug,微信拖动地图的时候,基本上算作是精准的,但是我们这里移动地图红色标记选择一个点然后松开手指之后,有时候没办法准确地拿到当前停留的点的准确地址。
对于这个bug,其实我也不想,但是高德给我的逆地理编码确实就是出不来的,有时很大一个范围拖动逆地理出来的都是同一个地址,如果我把点选在某一个大酒店或者标志性的地方的时候,是没什么问题的。
“
我眺望远方的山峰 却错过转弯的路口
蓦然回首 才发现你在等我 没离开过
我寻找大海的尽头 却不留蜿蜒的河流
当我逆水行舟 你在我左右 推着我走
……
”