2018-02-25 Android 高仿造微信發送位置(高德地圖版)

來吧,我們先來看一下原版的微信發送位置

嗯,是發送位置,為什么不帶發送實時位置,缺個另外一個真機。嗯,買一個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,其實我也不想,但是高德給我的逆地理編碼確實就是出不來的,有時很大一個范圍拖動逆地理出來的都是同一個地址,如果我把點選在某一個大酒店或者標志性的地方的時候,是沒什么問題的。

我眺望遠方的山峰 卻錯過轉彎的路口

驀然回首 才發現你在等我 沒離開過

我尋找大海的盡頭 卻不留蜿蜒的河流

當我逆水行舟 你在我左右 推著我走

……

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容