来吧,我们先来看一下原版的微信发送位置
嗯,是发送位置,为什么不带发送实时位置,缺个另外一个真机。嗯,买一个16年出的google亲儿子,嗯,信仰充值先想想就好!!!
接下来,再来看一下自己的程序gif
嗯哼,看完啦。
一、发送位置的需求分析
从原版微信的gif当中,我们看到,大概可以分为这么几个行为
1、进入页面,产生两个标记点,周围地点列表。两个标记点
一个是固定不变的当前位置的定位圆形标记,一个是可移动的红色标记。并且,会根据当前经纬度改变位置。地址列表
就是根据当前刚进入页面的经纬度搜索的出来的 附近poi (附近兴趣点)
2、当我们点击周围点的列表,列表更新圆形绿色切换,这点没什么好说,需要注意的是地图会动态改变位置
可移动的地图上的红色标记处于地图的中心点位置
3、当我们手动拖动地图,这时候两点注意当手势松开的时候,可移动红色标记移动并且居中
周围poi列表信息更新,而且第一条信息是我们当前屏幕的中心点所获取的地址,这个地址 逆地里编码 得到的,即经纬度转地址
4、点击搜索条关键字,按关键字进行搜索展示列表第一个poi信息作为默认选择item
如果我们不按下item,直接返回,那么之前页面的信息不变,地址照旧
如果我们按下item,那么该item作为之前页面的poi地址列表第一条item,并且搜索附近的poi信息。
(poi即兴趣点)
嗯,大概这么就是介么个样子,页面简单,写成文字还是看起来巴拉巴拉一大堆的。我们的demo大概也就是围绕着上面几点展开的。
二、环境说明
当前微信版本:6.3.25
android高德地图版本:
16年9月份官网给的。
测试机器:菊花荣耀7,Android6.0
IDE: AS
嗯,交代完毕。
三、开码
我们这里涉及到三个Activity,
分别是
JwActivity 得到定位,暂且叫做 A页面
ShareLocActivity 发送位置页面 暂且叫做 B页面
SeaechTextAddressActivity 搜索页面 暂且叫做 C页面
三.1、发送位置,最基本我们需要获得定位
之前弄得工具类,客官您将就着用
/** * User: LJM * Date&Time: 2016-08-17 & 22:36 * Describe: 获取经纬度工具类 * * 需要权限 * <!--用于进行网络定位--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!--用于访问GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <!--获取运营商信息,用于支持提供运营商信息相关的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <!--用于访问wifi网络信息,wifi信息会用于进行网络定位--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位--> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <!--用于访问网络,网络定位需要上网--> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <!--用于读取手机当前的状态--> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 需要在application 配置的mate-data 和sevice <service android:name="com.amap.api.location.APSService" > </service> <meta-data android:name="com.amap.api.v2.apikey" android:value="60f458d237f0494627e196293d49db7e"/> 另外,还需要一个key xxx.jks * */ public class AMapLocUtils implements AMapLocationListener { private AMapLocationClient locationClient = null; // 定位 private AMapLocationClientOption locationOption = null; // 定位设置 @Override public void onLocationChanged(AMapLocation aMapLocation) { mLonLatListener.getLonLat(aMapLocation); locationClient.stopLocation(); locationClient.onDestroy(); locationClient = null; locationOption = null; } private LonLatListener mLonLatListener; public void getLonLat(Context context, LonLatListener lonLatListener){ locationClient = new AMapLocationClient(context); locationOption = new AMapLocationClientOption(); locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);// 设置定位模式为高精度模式 locationClient.setLocationListener(this);// 设置定位监听 locationOption.setOnceLocation(false); // 单次定位 locationOption.setNeedAddress(true);//逆地理编码 mLonLatListener = lonLatListener;//接口 locationClient.setLocationOption(locationOption);// 设置定位参数 locationClient.startLocation(); // 启动定位 } public interface LonLatListener{ void getLonLat(AMapLocation aMapLocation); } }
好啦,调用一下,奔着分享位置的页面去拉
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_jw); mTvResult = (TextView) findViewById(R.id.mTvResult); mTvSendLoc = (TextView) findViewById(R.id.mTvSendLoc); mTvSendLoc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent openSend = new Intent(JwActivity.this,ShareLocActivity.class); openSend.putExtra("lon",mLongitude); openSend.putExtra("lat",mLatitude); openSend.putExtra("cityCode",cityCode); startActivity(openSend); } }); new AMapLocUtils().getLonLat(this, new AMapLocUtils.LonLatListener() { @Override public void getLonLat(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:
private GeocodeSearch geocoderSearch;
step2
geocoderSearch = new GeocodeSearch(this);
step3
/** * 根据经纬度得到地址 */ public void getAddress(final LatLng latLonPoint) { // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 RegeocodeQuery query = new RegeocodeQuery(convertToLatLonPoint(latLonPoint), 200, GeocodeSearch.AMAP); geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求 } /** * 逆地理编码回调 */ @Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { if (rCode == 1000) { if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) { addressName = result.getRegeocodeAddress().getFormatAddress(); // 逆转地里编码不是每次都可以得到对应地图上的opi L.d("逆地理编码回调 得到的地址:" + addressName); mAddressEntityFirst = new AddressSearchTextEntity(addressName, addressName, true, convertToLatLonPoint(mFinalChoosePosition)); } else { ToastUtil.show(ShareLocActivity.this, R.string.no_result); } } else if (rCode == 27) { ToastUtil.show(this, R.string.error_network); } else if (rCode == 32) { ToastUtil.show(this, R.string.error_key); } else { ToastUtil.show(this, getString(R.string.error_other) + rCode); } } /** * 地理编码查询回调 */ @Override public void onGeocodeSearched(GeocodeResult result, int rCode) { }
返回码1000表示转换成功,拿到我们RegeocodeResult的形参我们可以得到地址。
看个大概就行,后面附上这个页面的完整代码。
三.3、根据经纬度搜索周围poi信息
poi搜索分 搜索关键字 和 搜索经纬度。
官网的demo提供了搜索关键字的,但是没有?相应的按照经纬度的,其实做起来也差不多,但是一开始看文档找呀找找不到,为什么不也示例一下。
其实使用方法也是比较类似的。
1、首先我们要得到private PoiSearch.Query 的实例
2、设置 按需求设置搜索配置
2.1、按经纬度搜索该点周围的poi信息
/** * 开始进行poi搜索 重点 * 通过经纬度获取附近的poi信息 * <p> * 1、keyword 传 "" * 2、poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true)); 根据 */ protected void doSearchQuery() { currentPage = 0; query = new PoiSearch.Query("", "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setPageSize(20);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 LatLonPoint lpTemp = convertToLatLonPoint(mFinalChoosePosition); if (lpTemp != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); // 实现 onPoiSearched 和 onPoiItemSearched poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true));// // 设置搜索区域为以lp点为圆心,其周围5000米范围 poiSearch.searchPOIAsyn();// 异步搜索 } }
2.2、按照关键字搜索附近的poi信息
/** * 按照关键字搜索附近的poi信息 * @param key */ protected void doSearchQueryWithKeyWord(String key) { currentPage = 0; query = new PoiSearch.Query(key, "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setPageSize(20);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 if (lp != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); // 实现 onPoiSearched 和 onPoiItemSearched poiSearch.setBound(new PoiSearch.SearchBound(lp, 5000, true));// // 设置搜索区域为以lp点为圆心,其周围5000米范围 poiSearch.searchPOIAsyn();// 异步搜索 } }
不管是按照关键字还是按照经纬度,我们都要实现利用setOnPoiSearchListener实现搜索poi的接口,然后实现 onPoiSearched 和 onPoiItemSearched这两个方法,在关键onPoiSearched方法里面我们可以得到搜索的poi结果集合。
3、在onPoiSearched方法里面操作数据,更新列表
/** * poi 附近数据搜索 * * @param result * @param rcode */ @Override public void onPoiSearched(PoiResult result, int rcode) { if (rcode == 1000) { if (result != null && result.getQuery() != null) {// 搜索poi的结果 if (result.getQuery().equals(query)) {// 是否是同一条 poiResult = result; poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始 List<SuggestionCity> suggestionCities = poiResult .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息 mDatas.clear(); mDatas.add(mAddressEntityFirst);// 第一个元素 AddressSearchTextEntity addressEntity = null; for (PoiItem poiItem : poiItems) { L.d("得到的数据 poiItem " + poiItem.getSnippet()); addressEntity = new AddressSearchTextEntity(poiItem.getTitle(), poiItem.getSnippet(), false, poiItem.getLatLonPoint()); mDatas.add(addressEntity); } if (isHandDrag) { mDatas.get(0).isChoose = true; } mRvAddressAdapter.notifyDataSetChanged(); } } else { ToastUtil .show(ShareLocActivity.this, "对不起,没有搜索到相关数据!"); } } } @Override public void onPoiItemSearched(PoiItem poiitem, int rcode) { }
这么一个流程跑下来,poi数据就拿到了。
三.4、拖动地图
实现OnCameraChangeListener接口 mAMap.setOnCameraChangeListener(this);
实现 onCameraChange 和 onCameraChangeFinish两个方法
// 拖动地图 @Override public void onCameraChange(CameraPosition cameraPosition) { //L.d("拖动地图 onCameraChange "); } /** * 拖动地图 结束回调 * * @param cameraPosition 当地图位置发生变化,就重新查询数据(手动拖动或者代码改变地图位置都会调用) */ @Override public void onCameraChangeFinish(CameraPosition cameraPosition) { mFinalChoosePosition = cameraPosition.target; L.d("拖动地图 Finish changeCenterMarker 经度" + mFinalChoosePosition.longitude + " 纬度:" + mFinalChoosePosition.latitude); mIvCenter.startAnimation(animationMarker); if (isHandDrag||isFirstLoadList) {//手动去拖动地图 getAddress(cameraPosition.target); doSearchQuery(); } else if(isBackFromSearchChoose){ doSearchQuery(); }else{ mRvAddressAdapter.notifyDataSetChanged(); } isHandDrag = true; isFirstLoadList = false; }
这里需要注意的是,
mAMap.moveCamera方法可以通过代码手动移动地图,他会自动调用onCameraChangeFinish方法(OnCameraChangeListener按道理也是会的)
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lp.getLatitude(), lp.getLongitude()), 20));
嗯,大概就是这样子了。
至于C页面(就是我们在B页面按下搜索键跳转的页面,他其实也就是关键字搜索而且)
四、完整代码
接下我们看一下完整的B页面和C页面的代码把
B页面,分享位置页面
public class ShareLocActivity extends CheckPermissionsActivity implements View.OnClickListener, AMap.OnMapClickListener, PoiSearch.OnPoiSearchListener, AMap.OnCameraChangeListener, Animation.AnimationListener, GeocodeSearch.OnGeocodeSearchListener { private static final int OPEN_SEARCH = 0X0001; private MapView mapview; private AMap mAMap; private PoiResult poiResult; // poi返回的结果 private int currentPage = 0;// 当前页面,从0开始计数 private PoiSearch.Query query;// Poi查询条件类 private LatLonPoint lp;// private Marker locationMarker; // 选择的点 private PoiSearch poiSearch; private List<PoiItem> poiItems;// poi数据 private RelativeLayout mPoiDetail; private TextView mPoiName, mPoiAddress; private String keyWord = ""; private String city; private TextView mTvHint; private RelativeLayout search_bar_layout; private ImageView mIvCenter; private Animation animationMarker; private LatLng mFinalChoosePosition; //最终选择的点 private GeocodeSearch geocoderSearch; private String addressName; private RecyclerView mRvAddress; private RvAddressSearchTextAdapter mRvAddressAdapter; private ArrayList<AddressSearchTextEntity> mDatas = new ArrayList<>(); private AddressSearchTextEntity mAddressEntityFirst = null; private TextView mTvSearch; private boolean isHandDrag = true; private boolean isFirstLoadList = true; private boolean isBackFromSearchChoose = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_share_loc); Intent intent = getIntent(); double lon = intent.getDoubleExtra("lon", 0); double lat = intent.getDoubleExtra("lat", 0); city = intent.getStringExtra("cityCode"); lp = new LatLonPoint(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 = new LinearLayoutManager(ShareLocActivity.this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRvAddress.setLayoutManager(layoutManager); mRvAddressAdapter = new RvAddressSearchTextAdapter(ShareLocActivity.this, mDatas); mRvAddress.setAdapter(mRvAddressAdapter); mRvAddressAdapter.setOnItemClickLitener(new RvAddressSearchTextAdapter.OnItemClickLitener() { @Override public void onItemClick(View view, int position) { mFinalChoosePosition = convertToLatLng(mDatas.get(position).latLonPoint); for (int i = 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(new LatLng(mFinalChoosePosition.latitude, mFinalChoosePosition.longitude), 20)); } @Override public void onItemLongClick(View view, int position) { } }); init(); } /** * 初始化AMap对象 */ private void init() { 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(new MarkerOptions() .anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory .fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.point4))) .position(new LatLng(lp.getLatitude(), lp.getLongitude()))); mFinalChoosePosition = locationMarker.getPosition(); } setup(); // 只要地图发生改变,就会调用 onCameraChangeFinish ,不是说非要手动拖动屏幕才会调用该方法 mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lp.getLatitude(), lp.getLongitude()), 20)); } private void setup() { mPoiDetail = (RelativeLayout) findViewById(R.id.poi_detail); mPoiDetail.setOnClickListener(new View.OnClickListener() { @Override public void onClick(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 = new GeocodeSearch(this); geocoderSearch.setOnGeocodeSearchListener(this); mIvCenter.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ToastUtil.show(ShareLocActivity.this, "当前选择的经度:" + mFinalChoosePosition.longitude + " 纬度:" + mFinalChoosePosition.latitude); } }); } // 拖动地图 @Override public void onCameraChange(CameraPosition cameraPosition) { //L.d("拖动地图 onCameraChange "); } /** * 拖动地图 结束回调 * * @param cameraPosition 当地图位置发生变化,就重新查询数据(手动拖动或者代码改变地图位置都会调用) */ @Override public void onCameraChangeFinish(CameraPosition cameraPosition) { mFinalChoosePosition = cameraPosition.target; L.d("拖动地图 Finish changeCenterMarker 经度" + mFinalChoosePosition.longitude + " 纬度:" + mFinalChoosePosition.latitude); mIvCenter.startAnimation(animationMarker); if (isHandDrag||isFirstLoadList) {//手动去拖动地图 getAddress(cameraPosition.target); doSearchQuery(); } else if(isBackFromSearchChoose){ doSearchQuery(); }else{ mRvAddressAdapter.notifyDataSetChanged(); } isHandDrag = true; isFirstLoadList = false; } // ======== poi搜索 周边 以下 ===================== /** * 开始进行poi搜索 重点 * 通过经纬度获取附近的poi信息 * <p> * 1、keyword 传 "" * 2、poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true)); 根据 */ protected void doSearchQuery() { currentPage = 0; query = new PoiSearch.Query("", "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setPageSize(20);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 LatLonPoint lpTemp = convertToLatLonPoint(mFinalChoosePosition); if (lpTemp != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); // 实现 onPoiSearched 和 onPoiItemSearched poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true));// // 设置搜索区域为以lp点为圆心,其周围5000米范围 poiSearch.searchPOIAsyn();// 异步搜索 } } /** * poi 附近数据搜索 * * @param result * @param rcode */ @Override public void onPoiSearched(PoiResult result, int rcode) { if (rcode == 1000) { if (result != null && result.getQuery() != null) {// 搜索poi的结果 if (result.getQuery().equals(query)) {// 是否是同一条 poiResult = result; poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始 List<SuggestionCity> 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 = new AddressSearchTextEntity(poiItem.getTitle(), poiItem.getSnippet(), false, poiItem.getLatLonPoint()); mDatas.add(addressEntity); } if (isHandDrag) { mDatas.get(0).isChoose = true; } mRvAddressAdapter.notifyDataSetChanged(); } } else { ToastUtil .show(ShareLocActivity.this, "对不起,没有搜索到相关数据!"); } } } @Override public void onPoiItemSearched(PoiItem poiitem, int rcode) { } /** * 按照关键字搜索附近的poi信息 * @param key */ protected void doSearchQueryWithKeyWord(String key) { currentPage = 0; query = new PoiSearch.Query(key, "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setPageSize(20);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 if (lp != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); // 实现 onPoiSearched 和 onPoiItemSearched poiSearch.setBound(new PoiSearch.SearchBound(lp, 5000, true));// // 设置搜索区域为以lp点为圆心,其周围5000米范围 poiSearch.searchPOIAsyn();// 异步搜索 } } // ======== poi搜索 周边 以上 ===================== /** * 根据经纬度得到地址 */ public void getAddress(final LatLng latLonPoint) { // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 RegeocodeQuery query = new RegeocodeQuery(convertToLatLonPoint(latLonPoint), 200, GeocodeSearch.AMAP); geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求 } /** * 逆地理编码回调 */ @Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { if (rCode == 1000) { if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) { addressName = result.getRegeocodeAddress().getFormatAddress(); // 逆转地里编码不是每次都可以得到对应地图上的opi L.d("逆地理编码回调 得到的地址:" + addressName); mAddressEntityFirst = new AddressSearchTextEntity(addressName, addressName, true, convertToLatLonPoint(mFinalChoosePosition)); } else { ToastUtil.show(ShareLocActivity.this, R.string.no_result); } } else if (rCode == 27) { ToastUtil.show(this, R.string.error_network); } else if (rCode == 32) { ToastUtil.show(this, R.string.error_key); } else { ToastUtil.show(this, getString(R.string.error_other) + rCode); } } /** * 地理编码查询回调 */ @Override public void onGeocodeSearched(GeocodeResult result, int rCode) { } /** * 把LatLonPoint对象转化为LatLon对象 */ public LatLng convertToLatLng(LatLonPoint latLonPoint) { return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude()); } /** * 把LatLng对象转化为LatLonPoint对象 */ public static LatLonPoint convertToLatLonPoint(LatLng latlon) { return new LatLonPoint(latlon.latitude, latlon.longitude); } /** * 方法必须重写 */ @Override protected void onResume() { super.onResume(); mapview.onResume(); whetherToShowDetailInfo(false); } /** * 方法必须重写 */ @Override protected void onPause() { super.onPause(); mapview.onPause(); } /** * 方法必须重写 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapview.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mapview.onDestroy(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.mTvHint: case R.id.search_bar_layout: Intent intent = new Intent(ShareLocActivity.this, SeaechTextAddressActivity.class); intent.putExtra("point", mFinalChoosePosition); startActivityForResult(intent, OPEN_SEARCH); isBackFromSearchChoose = false; break; case R.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; } } private void whetherToShowDetailInfo(boolean isToShow) { if (isToShow) { mPoiDetail.setVisibility(View.VISIBLE); } else { mPoiDetail.setVisibility(View.GONE); } } // 单击地图 @Override public void onMapClick(LatLng latlng) { ToastUtil.show(ShareLocActivity.this, "点击地图结果: 经度:" + latlng.longitude + " 纬度: " + latlng.latitude); } /** * poi没有搜索到数据,返回一些推荐城市的信息 */ private void showSuggestCity(List<SuggestionCity> cities) { String infomation = "推荐城市\n"; for (int i = 0; i < cities.size(); i++) { infomation += "城市名称:" + cities.get(i).getCityName() + "城市区号:" + cities.get(i).getCityCode() + "城市编码:" + cities.get(i).getAdCode() + "\n"; } ToastUtil.show(this, infomation); } // 动画复写的三个方法 @Override public void onAnimationStart(Animation animation) { mIvCenter.setImageResource(R.drawable.poi_marker_pressed); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mIvCenter.setImageResource(R.drawable.poi_marker_pressed); } @Override protected void onActivityResult(int requestCode, int resultCode, 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(new LatLng(backEntity.latLonPoint.getLatitude(), backEntity.latLonPoint.getLongitude()), 20)); } } }
嗯。看起来长了一点,客官如果看到了这里也挺不容易的,就权且当个参考吧。哈哈哈
.
.
C页面
public class SeaechTextAddressActivity extends CheckPermissionsActivity implements PoiSearch.OnPoiSearchListener { private EditText mEtContent; private TextView mTvSearch; private String mSearchText; private LatLonPoint lp;// private PoiResult poiResult; // poi返回的结果 private List<PoiItem> poiItems;// poi数据 private int currentPage = 0;// 当前页面,从0开始计数 private PoiSearch.Query query;// Poi查询条件类 private PoiSearch poiSearch; private RecyclerView mRvSearchText; private RvAddressSearchTextAdapter mRvAddressSearchTextAdapter; private ArrayList<AddressSearchTextEntity> mDatas = new ArrayList<>(); //private AddressSearchTextEntity mAddressTextFirst = null; private String city = "深圳市"; // 这个需要完善 不能写死 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_text_address); initView(); } private void initView() { mEtContent = (EditText) findViewById(R.id.mEtContent); mTvSearch = (TextView) findViewById(R.id.mTvSearch); mRvSearchText = (RecyclerView) findViewById(R.id.mRvSearchText); LatLng point = (LatLng) getIntent().getParcelableExtra("point"); lp=new LatLonPoint(point.latitude,point.longitude); // Rv 列表 mRvSearchText = (RecyclerView) findViewById(R.id.mRvSearchText); LinearLayoutManager layoutManager = new LinearLayoutManager(SeaechTextAddressActivity.this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRvSearchText.setLayoutManager(layoutManager); mRvAddressSearchTextAdapter = new RvAddressSearchTextAdapter(SeaechTextAddressActivity.this,mDatas); mRvSearchText.setAdapter(mRvAddressSearchTextAdapter); mRvAddressSearchTextAdapter.setOnItemClickLitener(new RvAddressSearchTextAdapter.OnItemClickLitener() { @Override public void onItemClick(View view, int position) { Intent intent =new Intent(); AddressSearchTextEntity addressSearchTextEntity = mDatas.get(position); intent.putExtra("backEntity",addressSearchTextEntity); setResult(RESULT_OK,intent); finish(); } @Override public void onItemLongClick(View view, int position) { } }); mTvSearch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mSearchText = mEtContent.getText().toString().trim(); if (TextUtils.isEmpty(mSearchText)) { ToastUtil.show(SeaechTextAddressActivity.this, "请输入搜索关键字"); return; } else { doSearchQueryWithKeyWord(mSearchText); KeyBoardUtils.closeKeybord(mEtContent,SeaechTextAddressActivity.this); } } }); } protected void doSearchQueryWithKeyWord(String key) { currentPage = 0; query = new PoiSearch.Query(key, "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国) query.setPageSize(20);// 设置每页最多返回多少条poiitem query.setPageNum(currentPage);// 设置查第一页 query.setCityLimit(true); //限定城市 if (lp != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); // 实现 onPoiSearched 和 onPoiItemSearched poiSearch.setBound(new PoiSearch.SearchBound(lp, 5000, true));// // 设置搜索区域为以lp点为圆心,其周围5000米范围 poiSearch.searchPOIAsyn();// 异步搜索 } } @Override public void onPoiSearched(PoiResult result, int rcode) { if (rcode == 1000) { if (result != null && result.getQuery() != null) {// 搜索poi的结果 if (result.getQuery().equals(query)) {// 是否是同一条 poiResult = result; poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始 List<SuggestionCity> suggestionCities = poiResult .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息 mDatas.clear(); //mDatas.add(mAddressTextFirst);// 第一个元素 AddressSearchTextEntity addressEntity = null; for (int i=0;i<poiItems.size();i++) { PoiItem poiItem = poiItems.get(i); if(i==0){ addressEntity = new AddressSearchTextEntity(poiItem.getTitle(),poiItem.getSnippet(),true,poiItem.getLatLonPoint()); }else{ addressEntity = new AddressSearchTextEntity(poiItem.getTitle(),poiItem.getSnippet(),false,poiItem.getLatLonPoint()); } L.d("得到的数据 poiItem " + "\npoiItem.getSnippet()"+poiItem.getSnippet() + "\npoiItem.getAdCode()"+poiItem.getAdCode() + "\npoiItem.getAdName()"+poiItem.getAdName() + "\npoiItem.getDirection()"+poiItem.getDirection() + "\npoiItem.getBusinessArea()"+poiItem.getBusinessArea() + "\npoiItem.getCityCode()"+poiItem.getCityCode() + "\npoiItem.getEmail()"+poiItem.getEmail() + "\npoiItem.getParkingType()"+poiItem.getParkingType() + "\npoiItem.getCityName()"+poiItem.getCityName() + "\npoiItem.getProvinceName()"+poiItem.getProvinceName() + "\npoiItem.getSnippet()"+poiItem.getSnippet() + "\npoiItem.getTitle()"+poiItem.getTitle() + "\npoiItem.getTypeDes()"+poiItem.getTypeDes() + "\npoiItem.getDistance()"+poiItem.getDistance() + "\npoiItem.getWebsite()"+poiItem.getWebsite() ); mDatas.add(addressEntity); } mRvAddressSearchTextAdapter.notifyDataSetChanged(); } } else { ToastUtil .show(SeaechTextAddressActivity.this, "对不起,没有搜索到相关数据!"); } } } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { } }
嗯,到这里就差不多了。
其实结合官方demo,折腾起来也就差不多了。
程序有一个小bug,微信拖动地图的时候,基本上算作是精准的,但是我们这里移动地图红色标记选择一个点然后松开手指之后,有时候没办法准确地拿到当前停留的点的准确地址。
对于这个bug,其实我也不想,但是高德给我的逆地理编码确实就是出不来的,有时很大一个范围拖动逆地理出来的都是同一个地址,如果我把点选在某一个大酒店或者标志性的地方的时候,是没什么问题的。
“
我眺望远方的山峰 却错过转弯的路口
蓦然回首 才发现你在等我 没离开过
我寻找大海的尽头 却不留蜿蜒的河流
当我逆水行舟 你在我左右 推着我走
……
”
网易大晚上推过来的歌听起来好激情~~~
共同学习,写下你的评论
评论加载中...
作者其他优质文章