Android高德地圖poi檢索仿微信發(fā)送位置實(shí)例代碼
最近項(xiàng)目需求把發(fā)送定位模塊改成類(lèi)似微信發(fā)送位置給好友的效果,我使用了高德地圖實(shí)現(xiàn)了一個(gè)demo,效果圖如下:

從主界面中我們可以看到中心標(biāo)記上面顯示的就是我們定位的地址,下面是一個(gè)listview列表,第一條item的數(shù)據(jù)就是我們定位得到的地址,下面其余的都是我們根據(jù)定位得到的經(jīng)緯度通過(guò)poi周邊搜索得到的地址。我們進(jìn)行了如下操作:
- 我們點(diǎn)擊列表的item,中心標(biāo)記會(huì)移動(dòng)到該item對(duì)象的地址上面去。
- 我們手動(dòng)移動(dòng)地圖的時(shí)候,中心標(biāo)記的地址會(huì)發(fā)生相應(yīng)的變化并且下面的列表也會(huì)發(fā)生相應(yīng)的變化。
- 根據(jù)關(guān)鍵字poi搜索得到的列表,然后點(diǎn)擊item主界面立馬進(jìn)行更新操作。
這里貼出主要代碼,首先我們進(jìn)行地圖地位初始化操作:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mapView.onCreate(savedInstanceState);// 此方法必須重寫(xiě)
if (aMap == null) {
aMap = mapView.getMap();
// 自定義系統(tǒng)定位小藍(lán)點(diǎn)
MyLocationStyle myLocationStyle = new MyLocationStyle();
// 設(shè)置小藍(lán)點(diǎn)的圖標(biāo)
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
fromResource(R.mipmap.ic_location_marker));// 設(shè)置小藍(lán)點(diǎn)的圖標(biāo)
myLocationStyle.strokeColor(0x7F0070D9);// 設(shè)置圓形的邊框顏色
myLocationStyle.radiusFillColor(0x130070D9);// 設(shè)置圓形的填充顏色
// myLocationStyle.anchor(int,int)//設(shè)置小藍(lán)點(diǎn)的錨點(diǎn)
myLocationStyle.strokeWidth(1.0f);// 設(shè)置圓形的邊框粗細(xì)
aMap.setMyLocationStyle(myLocationStyle);
aMap.setLocationSource(this);// 設(shè)置定位(1)
aMap.setOnCameraChangeListener(this);//手動(dòng)移動(dòng)地圖 (2)
aMap.getUiSettings().setMyLocationButtonEnabled(true);// 設(shè)置默認(rèn)定位按鈕是否顯示
//設(shè)置為true表示顯示定位層并可觸發(fā)定位,false表示隱藏定位層并不可觸發(fā)定位,默認(rèn)是false
aMap.setMyLocationEnabled(true);
aMap.moveCamera(CameraUpdateFactory.zoomTo(17.5f));
}
//------------------------------------------添加中心標(biāo)記
mMarkerOptions = new MarkerOptions();
mMarkerOptions.draggable(false);//可拖放性
mMarkerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_tips_nearby));
mCenterMarker = aMap.addMarker(mMarkerOptions);
ViewTreeObserver vto = mapView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mCenterMarker.setPositionByPixels(mapView.getWidth() >> 1, mapView.getHeight() >> 1);
mCenterMarker.showInfoWindow();
}
});
//---------------------------------------------初始化正反編碼類(lèi) (3)
mGeocoderSearch = new GeocodeSearch(this);
mGeocoderSearch.setOnGeocodeSearchListener(this);
}
我們注意重點(diǎn)關(guān)注在上面的三個(gè)回調(diào),1處是定位,有以下兩個(gè)回調(diào)方法:
//-----------------地圖定位回調(diào)
//激活定位
@Override
public void activate(OnLocationChangedListener onLocationChangedListener) {
mListener = onLocationChangedListener;
if (mlocationClient == null) {
mlocationClient = new AMapLocationClient(this);
mLocationOption = new AMapLocationClientOption();
//設(shè)置定位
mlocationClient.setLocationListener(this);(4)
//設(shè)置為高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//設(shè)置定位參數(shù)
mlocationClient.setLocationOption(mLocationOption);
// 此方法為每隔固定時(shí)間會(huì)發(fā)起一次定位請(qǐng)求,為了減少電量消耗或網(wǎng)絡(luò)流量消耗,
// 注意設(shè)置合適的定位時(shí)間的間隔(最小間隔支持為2000ms),并且在合適時(shí)間調(diào)用stopLocation()
// 方法來(lái)取消定位請(qǐng)求
// 在定位結(jié)束后,在合適的生命周期調(diào)用onDestroy()方法
// 在單次定位情況下,定位無(wú)論成功與否,都無(wú)需調(diào)用stopLocation()方法移除請(qǐng)求,定位sdk內(nèi)部會(huì)移除
mlocationClient.startLocation();
}
}
//停止定位
@Override
public void deactivate() {
mListener = null;
if (mlocationClient != null) {
mlocationClient.stopLocation();
mlocationClient.onDestroy();
}
mlocationClient = null;
}
4處的定位成功后會(huì)回調(diào)onLocationChanged這個(gè)方法,在這個(gè)方法里面我們可以獲得定位到的經(jīng)緯讀,地址,顯示出上面我們?cè)O(shè)置的自定義系統(tǒng)定位小藍(lán)點(diǎn)出來(lái)等等,
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
//這個(gè)方法循環(huán)執(zhí)行
mLongitude = aMapLocation.getLongitude();//經(jīng)度
mLatitude = aMapLocation.getLatitude();//緯度
cityCode = aMapLocation.getCityCode();//citycode
}
我們?cè)賮?lái)分析2處地圖位置改變時(shí)回調(diào):
@Override
public void onCameraChange(CameraPosition cameraPosition) {
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
/**這個(gè)方法很重要,雖然在上述的onLocationChanged方法我們也能獲得坐標(biāo)點(diǎn)的信息但是我們
通常在這里獲得定位坐標(biāo)的經(jīng)緯度,獲得了經(jīng)緯度后我們并不能知道該坐標(biāo)點(diǎn)的具體坐標(biāo)信息,所以
需要把對(duì)應(yīng)的坐標(biāo)點(diǎn)轉(zhuǎn)化為具體地址,這就是所謂的同步逆地理編碼請(qǐng)求,和定位是黃金搭檔
*/
mCurrentPoint = new LatLonPoint(cameraPosition.target.
latitude, cameraPosition.target.longitude);
// 第一個(gè)參數(shù)表示一個(gè)Latlng,第二參數(shù)表示范圍多少米,第三個(gè)參數(shù)表示是火系坐標(biāo)系還是GPS原生坐標(biāo)系
RegeocodeQuery query = new RegeocodeQuery(mCurrentPoint, 200, GeocodeSearch.AMAP);
mGeocoderSearch.getFromLocationAsyn(query);// 設(shè)置同步逆地理編碼請(qǐng)求
}
3處我們做的地理正反編碼回調(diào)如下:
//----------------逆地址編碼回調(diào):坐標(biāo)->地址
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
if (rCode == 0) {
if (result != null && result.getRegeocodeAddress() != null &&
result.getRegeocodeAddress().getFormatAddress() != null) {
mPoiQuery = new PoiSearch.Query("", "住宿服務(wù)|公司企業(yè)",
result.getRegeocodeAddress().getCityCode());
mPoiQuery.setPageSize(10);// 設(shè)置每頁(yè)最多返回多少條poiitem
mPoiQuery.setPageNum(0);//設(shè)置查第一頁(yè)
PoiSearch poiSearch = new PoiSearch(this, mPoiQuery);
poiSearch.setOnPoiSearchListener(this);//設(shè)置數(shù)據(jù)返回 (5)
//設(shè)置周邊搜索的中心點(diǎn)以及區(qū)域
poiSearch.setBound(new PoiSearch.SearchBound(mCurrentPoint, 1500, true));
poiSearch.searchPOIAsyn();//開(kāi)始搜索
} else {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.show(mContexts, rCode);
}
}
//----------------地址編碼回調(diào):地址->坐標(biāo)
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int rCode) {
}
我們?cè)谶@兒進(jìn)行了poi周邊搜索操作,回調(diào)方法
@Override
public void onPoiSearched(PoiResult result, int rcode) {
if (rcode == 0) {
if (result != null && result.getQuery() != null) {// 搜索poi的結(jié)果
if (result.getQuery().equals(query)) {// 是否是同一條
poiItems = poiResult.getPois();// 取得第一頁(yè)的poiitem數(shù)據(jù),頁(yè)數(shù)從數(shù)字0開(kāi)始
// 當(dāng)搜索不到poiitem數(shù)據(jù)時(shí),會(huì)返回含有搜索關(guān)鍵字的城市信息
List<SuggestionCity> suggestionCities = poiResult
.getSearchSuggestionCitys();
/**
* listviw具體操作邏輯
*/
}
} else if (suggestionCities != null
&& suggestionCities.size() > 0) {
showSuggestCity(suggestionCities);
}else {
ToastUtil.show(mContexts, "對(duì)不起,沒(méi)有搜索到相關(guān)數(shù)據(jù)!");
}
}
}
@Override
public void onPoiItemSearched(PoiItem poiitem, int rcode) {
}
/**
* poi沒(méi)有搜索到數(shù)據(jù),返回一些推薦城市的信息
*/
private void showSuggestCity(List<SuggestionCity> cities) {
String infomation = "推薦城市\(zhòng)n";
for (int i = 0; i < cities.size(); i++) {
infomation += "城市名稱(chēng):" + cities.get(i).getCityName() + "城市區(qū)號(hào):"
+ cities.get(i).getCityCode() + "城市編碼:"
+ cities.get(i).getAdCode() + "\n";
}
ToastUtil.show(this, infomation);
}
類(lèi)似的含關(guān)鍵字的poi搜索也是類(lèi)似的:
// 第一個(gè)參數(shù)表示搜索字符串,第二個(gè)參數(shù)表示poi搜索類(lèi)型,第三個(gè)參數(shù)表示poi搜索區(qū)域(空字符串代表全國(guó))
mPoiQuery = new PoiSearch.Query(key, "", cityCode);
mPoiSearch = new PoiSearch(this, mPoiQuery);
mPoiQuery.setPageSize(15);// 設(shè)置每頁(yè)最多返回多少條poiitem
mPoiQuery.setPageNum(0);//設(shè)置查第一頁(yè)
mPoiSearch.setOnPoiSearchListener(this);
// 設(shè)置搜索區(qū)域?yàn)橐詌p點(diǎn)為圓心,其周?chē)?000米范圍
LatLonPoint lp=new LatLonPoint(latitude,longitude);
mPoiSearch.setBound(new PoiSearch.SearchBound(lp, 5000, true));
mPoiSearch.searchPOIAsyn();//開(kāi)始搜索最后還有一個(gè)知識(shí)點(diǎn)就是我們點(diǎn)擊item的時(shí)候地圖自動(dòng)去移動(dòng)的實(shí)現(xiàn),其實(shí)就是aMap.moveCamera方法去實(shí)現(xiàn)的,它會(huì)自動(dòng)調(diào)用onCameraChangeFinish方法走的流程還是和我們手動(dòng)拖動(dòng)地圖一樣的。
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude()), 20));
基本上就是這樣了,至于一些細(xì)節(jié)方面自己去調(diào)節(jié)和優(yōu)化吧,哪些問(wèn)題都不大。以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Lock鎖實(shí)現(xiàn)原理詳細(xì)分析
這篇文章主要介紹了Android Lock鎖實(shí)現(xiàn)原理,Lock接口的實(shí)現(xiàn)類(lèi)提供了比使用synchronized關(guān)鍵字更加靈活和廣泛的鎖定對(duì)象操作,而且是以面向?qū)ο蟮姆绞竭M(jìn)行對(duì)象加鎖2023-02-02
Android實(shí)現(xiàn)GridView中的item自由拖動(dòng)效果
在前一個(gè)項(xiàng)目中,實(shí)現(xiàn)了一個(gè)功能是gridview中的item自由拖到效果,實(shí)現(xiàn)思路很簡(jiǎn)單,主要工作就是交換節(jié)點(diǎn),以及拖動(dòng)時(shí)的移動(dòng)效果,下面小編給大家分享具體實(shí)現(xiàn)過(guò)程,對(duì)gridview實(shí)現(xiàn)拖拽效果感興趣的朋友一起看看吧2016-11-11
Android自定義實(shí)現(xiàn)開(kāi)關(guān)按鈕代碼
經(jīng)??梢钥吹揭恍┻x擇開(kāi)個(gè)狀態(tài)的配置文件,但是外觀都不多好看。我感覺(jué)還是自定義的比較好,下面小編給大家介紹通過(guò)Android自定義實(shí)現(xiàn)開(kāi)關(guān)按鈕代碼,感興趣的童鞋一起學(xué)習(xí)吧2016-05-05
android基本控件ToggleButton&Switch使用指南
本文給大家匯總介紹了android的2個(gè)基本控件ToggleButton和Switch的使用方法,非常的詳細(xì),有需要的小伙伴可以參考下。2016-01-01
Android 使用ViewPager實(shí)現(xiàn)輪播圖效果
這篇文章主要介紹了Android 使用ViewPager實(shí)現(xiàn)輪播圖效果,通過(guò)實(shí)例代碼給大家講解了適配器和各個(gè)方法的作用介紹,需要的朋友可以參考下2017-05-05
Android編程操作嵌入式關(guān)系型SQLite數(shù)據(jù)庫(kù)實(shí)例詳解
這篇文章主要介紹了Android編程操作嵌入式關(guān)系型SQLite數(shù)據(jù)庫(kù)的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android操作SQLite數(shù)據(jù)庫(kù)的基本技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-01-01
Android實(shí)現(xiàn)圖片轉(zhuǎn)高斯模糊以及高斯模糊布局
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片轉(zhuǎn)高斯模糊的方法,以及高斯模糊布局,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android自定義View實(shí)現(xiàn)shape圖形繪制
這篇文章主要為大家詳細(xì)介紹了Android使用自定義View實(shí)現(xiàn)shape圖形繪制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01

