emmmm,效果圖先行(搜索定位以及自由滑動地圖展示周邊位置信息,根據(jù)點(diǎn)擊的位置獲取經(jīng)緯度)
主要代碼
package com.dydd.wsp.dreamtree.ui.map
import android.content.Context
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.KeyEvent
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.LocationSource
import com.amap.api.maps.model.*
import com.dydd.wsp.dreamtree.R
import com.dydd.wsp.dreamtree.ui.base.BaseActivity
import com.dydd.wsp.dreamtree.utils.LocationInfo
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.dydd.wsp.dreamtree.ui.adapter.common.CommonAdapter
import com.dydd.wsp.dreamtree.ui.adapter.common.ViewHolder
import com.dydd.wsp.dreamtree.utils.InitAmap.initAmap
import com.dydd.wsp.dreamtree.utils.TOT
import com.dydd.wsp.dreamtree.utils.getLatLngByAddress
import kotlinx.android.synthetic.main.activity_map_search.*
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
/**
* Created by ${吳心良} on 2018/7/5.
* E-mail:wusongpingsmile@gmail.com
* Describe:搜索地址展示附近地址
*/
class MapSearchActivity : BaseActivity() {
private lateinit var aMap: AMap
private var locationMaker: Marker? = null
private var mListener: LocationSource.OnLocationChangedListener? = null
override fun bindLayout() = R.layout.activity_map_search
override fun beforeSetContentView() {
super.beforeSetContentView()
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
}
override fun init(savedInstanceState: Bundle?) {
//初始化地圖
map_ams.onCreate(savedInstanceState)
aMap = map_ams.map
initAmap(aMap, { locationSourceListener(it) }, { markerListener(it) })
//設(shè)置地圖拖動監(jiān)聽
aMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
override fun onCameraChangeFinish(cameraPosition: CameraPosition) {
val latLng = cameraPosition.target
searchNearby(latLng)
}
override fun onCameraChange(p0: CameraPosition?) {
}
})
//定位初始化
LocationInfo.getLocationInfo(this, {
locationSuccess(it)
})
//搜索框監(jiān)聽
et_search_ams.setOnKeyListener { v, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_ENTER) {
val string = et_search_ams.text.toString()
getLatLngByAddress(this, string, string, { getLatlngSuccess(it) })
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
// 強(qiáng)制隱藏軟鍵盤
imm.hideSoftInputFromWindow(et_search_ams.windowToken, 0)
}
false
}
}
private fun locationSourceListener(locationSource: LocationSource.OnLocationChangedListener?) {
mListener = locationSource
}
//marker的點(diǎn)擊事件監(jiān)聽
private fun markerListener(marker: Marker): Boolean {
return true
}
private fun locationSuccess(location: AMapLocation) {
//顯示系統(tǒng)小藍(lán)點(diǎn)
mListener?.let { mListener!!.onLocationChanged(location) }
// 設(shè)置縮放級別
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location.latitude, location.longitude), 17f))
// 將地圖移動到定位點(diǎn)
aMap.moveCamera(CameraUpdateFactory.changeLatLng(
LatLng(location.latitude, location.longitude)))
val markerOption = MarkerOptions()
markerOption
.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_location))
.position(LatLng(location.latitude, location.longitude))
.draggable(true)
.title("")
.snippet("哼哼哈哈哈")
locationMaker = aMap.addMarker(markerOption)
locationMaker?.setPositionByPixels(map_ams.width / 2,
map_ams.height / 2)
searchNearby(LatLng(location.latitude, location.longitude))
}
/**
* 開始搜索附近
*/
private fun searchNearby(latLng: LatLng) {
//這三個(gè)參數(shù)杨刨,第一個(gè)是搜索關(guān)鍵字晤柄,第二個(gè)是搜索的類型,具體類型參照高德api
val query = PoiSearch.Query("", "", "")
//查詢條數(shù)
query.pageSize = 6
val search = PoiSearch(this, query)
search.bound = PoiSearch.SearchBound(LatLonPoint(latLng.latitude, latLng.longitude), 10000)
search.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
override fun onPoiItemSearched(p0: PoiItem?, p1: Int) {
}
override fun onPoiSearched(result: PoiResult?, code: Int) {
if (code == 1000) {
val query = result?.query
val pois = result?.pois
rlv_search_ams.layoutManager = LinearLayoutManager(this@MapSearchActivity)
rlv_search_ams.adapter = object : CommonAdapter<PoiItem>(this@MapSearchActivity
, R.layout.item_rlv_search_ams, pois) {
override fun convert(holder: ViewHolder, t: Any?, position: Int) {
val data = t as PoiItem
holder.setText(R.id.tv_title_irsa, data.title)
holder.setText(R.id.tv_address_irsa, data.snippet)
holder.convertView.setOnClickListener {
val address = data.provinceName + data.cityName + data.adName + data.snippet
Log.e("aa", "點(diǎn)擊的地址:$address")
getLatLngByAddress(this@MapSearchActivity, data.cityCode, address, { getLatlngSuccess(it) })
}
}
}
} else {
TOT("搜索錯誤")
}
}
})
search.searchPOIAsyn()
}
private fun getLatlngSuccess(geocodeResult: GeocodeResult) {
val address = geocodeResult.geocodeAddressList[0]
Log.e("aa", ("經(jīng)緯度值:" + address.latLonPoint + "\n位置描述:"
+ address.formatAddress))
val latLng = LatLng(address.latLonPoint.latitude, address.latLonPoint.longitude)
searchNearby(latLng)
aMap.moveCamera(CameraUpdateFactory.changeLatLng(latLng))
//設(shè)置返回值
}
override fun onResume() {
super.onResume()
// 重新繪制加載地圖
map_ams.onResume()
}
override fun onPause() {
super.onPause()
// 暫停地圖的繪制
map_ams.onPause()
}
override fun onDestroy() {
super.onDestroy()
// 銷毀地圖
map_ams.onDestroy()
}
}
html代碼
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.amap.api.maps.MapView
android:id="@+id/map_ams"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.amap.api.maps.MapView>
<android.support.v7.widget.RecyclerView
android:id="@+id/rlv_search_ams"
android:background="@color/colorWhite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingBottom="12dp">
</android.support.v7.widget.RecyclerView>
<EditText
android:id="@+id/et_search_ams"
android:layout_width="match_parent"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:padding="8dp"
android:hint="輸入詳細(xì)地址查詢"
android:background="@drawable/shape_fill_white_with_gray_rec_bg"/>
</FrameLayout>
用到的工具類方法:
1妖胀、initAmap
object InitAmap {
fun initAmap(aMap: AMap, locationSource: (LocationSource.OnLocationChangedListener?) -> Unit,
marker: (Marker) -> Boolean) {
aMap.uiSettings.isZoomControlsEnabled = false
// 設(shè)置地圖默認(rèn)的指南針是否顯示
aMap.uiSettings.isCompassEnabled = false
// 設(shè)置定位監(jiān)聽
aMap.setLocationSource(object : LocationSource {
override fun deactivate() {
}
override fun activate(p0: LocationSource.OnLocationChangedListener?) {
locationSource(p0)
}
})
// 設(shè)置默認(rèn)定位按鈕是否顯示
aMap.uiSettings.isMyLocationButtonEnabled = false
// 設(shè)置為true表示顯示定位層并可觸發(fā)定位芥颈,false表示隱藏定位層并不可觸發(fā)定位惠勒,默認(rèn)是false
aMap.isMyLocationEnabled = true
// aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE)
aMap.setOnMarkerClickListener {
marker(it)
}
}
}
2、定位信息
object LocationInfo {
fun getLocationInfo(context: Context, success: (AMapLocation) -> Unit) {
val mLocationClient = AMapLocationClient(context)
val mLocationOption = AMapLocationClientOption()
// 初始化定位
// 設(shè)置高德地圖定位回調(diào)監(jiān)聽
mLocationClient.setLocationListener { aMapLocation ->
if (aMapLocation != null) {
if (aMapLocation.errorCode == 0) {
val locationType = aMapLocation.locationType // 獲取當(dāng)前定位結(jié)果來源爬坑,如網(wǎng)絡(luò)定位結(jié)果纠屋,詳見定位類型表
val latitude = aMapLocation.latitude // 獲取緯度
val longitude = aMapLocation.longitude // 獲取經(jīng)度
val accuracy = aMapLocation.accuracy // 獲取精度信息
val address = aMapLocation.address // 地址,如果option中設(shè)置isNeedAddress為false盾计,則沒有此結(jié)果售担,
// 網(wǎng)絡(luò)定位結(jié)果中會有地址信息,GPS定位不返回地址信息署辉。
val country = aMapLocation.country // 國家信息
val province = aMapLocation.province // 省信息
val city = aMapLocation.city // 城市信息
val district = aMapLocation.district // 城區(qū)信息
val street = aMapLocation.street // 街道信息
val streetNum = aMapLocation.streetNum // 街道門牌號信息
val cityCode = aMapLocation.cityCode // 城市編碼
val adCode = aMapLocation.adCode // 地區(qū)編碼
val aoiName = aMapLocation.aoiName // 獲取當(dāng)前定位點(diǎn)的AOI信息
val buildingId = aMapLocation.buildingId // 獲取當(dāng)前室內(nèi)定位的建筑物Id
val floor = aMapLocation.floor // 獲取當(dāng)前室內(nèi)定位的樓層
val gpsAccuracyStatus = aMapLocation.gpsAccuracyStatus //獲取GPS的當(dāng)前狀態(tài)
// 獲取定位時(shí)間
val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val date = Date(aMapLocation.time)
df.format(date)
success(aMapLocation)
} else {
// 定位失敗時(shí)族铆,可通過ErrCode(錯誤碼)信息來確定失敗的原因,errInfo是錯誤信息哭尝,詳見錯誤碼表哥攘。
TOT("獲取定位失敗")
}
}
}
// 初始化AMapLocationClientOption對象
// 高精度定位模式:會同時(shí)使用網(wǎng)絡(luò)定位和GPS定位,優(yōu)先返回最高精度的定位結(jié)果材鹦,以及對應(yīng)的地址描述信息
// 設(shè)置定位模式為AMapLocationMode.Hight_Accuracy逝淹,高精度模式
mLocationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
// 低功耗定位模式:不會使用GPS和其他傳感器,只會使用網(wǎng)絡(luò)定位(Wi-Fi和基站定位)桶唐;
//設(shè)置定位模式為AMapLocationMode.Battery_Saving栅葡,低功耗模式。
//mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
// 僅用設(shè)備定位模式:不需要連接網(wǎng)絡(luò)尤泽,只使用GPS進(jìn)行定位妥畏,這種模式下不支持室內(nèi)環(huán)境的定位,自 v2.9.0 版本支持返回地址描述信息安吁。
// 設(shè)置定位模式為AMapLocationMode.Device_Sensors醉蚁,僅設(shè)備模式。
//mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Device_Sensors);
// SDK默認(rèn)采用連續(xù)定位模式鬼店,時(shí)間間隔2000ms
// 設(shè)置定位間隔网棍,單位毫秒,默認(rèn)為2000ms妇智,最低1000ms滥玷。
mLocationOption.interval = 60000
// 設(shè)置定位同時(shí)是否需要返回地址描述
//設(shè)置是否返回地址信息(默認(rèn)返回地址信息)
mLocationOption.isNeedAddress = true
// 設(shè)置是否強(qiáng)制刷新WIFI,默認(rèn)為強(qiáng)制刷新巍棱。每次定位主動刷新WIFI模塊會提升WIFI定位精度惑畴,但相應(yīng)的會多付出一些電量消耗。
// 設(shè)置是否強(qiáng)制刷新WIFI航徙,默認(rèn)為true如贷,強(qiáng)制刷新。
// mLocationOption.isWifiActiveScan = true
// 設(shè)置是否允許模擬軟件Mock位置結(jié)果,多為模擬GPS定位結(jié)果杠袱,默認(rèn)為false尚猿,不允許模擬位置。
// 設(shè)置是否允許模擬位置,默認(rèn)為false楣富,不允許模擬位置
mLocationOption.isMockEnable = false
// 設(shè)置定位請求超時(shí)時(shí)間凿掂,默認(rèn)為30秒
// 單位是毫秒,默認(rèn)30000毫秒纹蝴,建議超時(shí)時(shí)間不要低于8000毫秒庄萎。
mLocationOption.httpTimeOut = 50000
// 設(shè)置是否開啟定位緩存機(jī)制
// 緩存機(jī)制默認(rèn)開啟,可以通過以下接口進(jìn)行關(guān)閉塘安。
// 當(dāng)開啟定位緩存功能糠涛,在高精度模式和低功耗模式下進(jìn)行的網(wǎng)絡(luò)定位結(jié)果均會生成本地緩存,不區(qū)分單次定位還是連續(xù)定位耙旦。GPS定位結(jié)果不會被緩存。
// 關(guān)閉緩存機(jī)制
mLocationOption.isLocationCacheEnable = false
// 設(shè)置是否只定位一次萝究,默認(rèn)為false
mLocationOption.isOnceLocation = true
// 給定位客戶端對象設(shè)置定位參數(shù)
mLocationClient.setLocationOption(mLocationOption)
// 啟動高德地圖定位
mLocationClient.startLocation()
}
}
3免都、根據(jù)地址獲取經(jīng)緯度
fun getLatLngByAddress(context: Context,city:String,address:String,success:(GeocodeResult)->Unit){
//發(fā)起正地理編碼搜索
//構(gòu)造 GeocodeSearch 對象,并設(shè)置監(jiān)聽帆竹。
val geocodeSearch = GeocodeSearch(context)
geocodeSearch.setOnGeocodeSearchListener(object :GeocodeSearch.OnGeocodeSearchListener{
override fun onRegeocodeSearched(p0: RegeocodeResult?, position: Int) {
}
override fun onGeocodeSearched(geocodeResult: GeocodeResult?, position: Int) {
if (position == AMapException.CODE_AMAP_SUCCESS) {
if (geocodeResult?.geocodeAddressList != null
&& geocodeResult.geocodeAddressList.size > 0) {
success(geocodeResult)
}
}
}
})
//通過GeocodeQuery設(shè)置查詢參數(shù),調(diào)用getFromLocationNameAsyn(GeocodeQuery geocodeQuery) 方法發(fā)起請求绕娘。
//address表示地址,第二個(gè)參數(shù)表示查詢城市栽连,中文或者中文全拼险领,citycode、adcode都o(jì)k
val query =GeocodeQuery(address, city)
geocodeSearch.getFromLocationNameAsyn(query)
}
應(yīng)該夠詳細(xì)了秒紧,下次能直接拿著就用了绢陌,美滋滋,希望能有人用得到