在谷歌地图安卓上放置窃听器



我有一个带有地图片段的android应用程序。地图显示了位置,我正在寻找一种方法,当用户点击它们时,可以添加一个监听器来获取该位置。

我发现的最相关的信息是建议添加一个监听器来点击地图,获取长&lat,然后在此基础上搜索位置。我想我可以使用FetchPlaceRequest来实现这一点,但在实例化时,这似乎首先需要placeId

我是不是错过了一些基本的东西?

编辑

包含映射的片段的代码(我认为实现PlaceSelectionlistener可以完成这项工作(

class MapFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener,
PlaceSelectionListener, KoinComponent {
private lateinit var mapViewModel: MapViewModel
private lateinit var map: GoogleMap
private var fusedLocationClient: FusedLocationProviderClient? = null
private var locationRequest: LocationRequest? = null
private var locationCallback: LocationCallback? = null
private val permissionsUtils : PermissionsUtils by inject()
private val preferencesUtils : PreferencesUtils by inject { parametersOf(activity!!.applicationContext)}
private var root : View? = null
private val defaultZoom : Float = 16f
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mapViewModel = ViewModelProviders.of(this).get(MapViewModel::class.java)
root = inflater.inflate(R.layout.fragment_map, container, false)
if (canAccessLocation()) {
initialiseMap(true)
} else {
val permissions = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
requestPermissions(permissions, PermissionRequests.FineLocation.value)
}
return root
}
override fun onMarkerClick(p0: Marker?) = false
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
map.setMapStyle(MapStyleOptions
.loadRawResourceStyle(activity!!.applicationContext, preferencesUtils.mapMode))
map.uiSettings.isZoomControlsEnabled = true
if (canAccessLocation()){
map.isMyLocationEnabled = true
map.uiSettings.isMyLocationButtonEnabled = true
}
map.setOnMarkerClickListener(this)
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
PermissionRequests.FineLocation.value -> {
val permissionGranted = grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
initialiseMap(permissionGranted)
}
}
}
override fun onPause() {
super.onPause()
fusedLocationClient?.removeLocationUpdates(locationCallback)
}
override fun onResume() {
super.onResume()
requestLocationUpdates()
}
override fun onPlaceSelected(status: Place) {
val toast = Toast.makeText(activity!!.applicationContext,""+ status!!.name + status!!.latLng, Toast.LENGTH_LONG)
toast.setGravity(Gravity.TOP, 0, 0)
toast.show()
}
override fun onError(status: Status) {
Toast.makeText(activity!!.applicationContext,"" + status.toString(), Toast.LENGTH_LONG)
.show()
}
private fun initialiseMap(withLocation: Boolean) {
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
if (!withLocation) {
return
}
requestLocationUpdates()
}
private fun requestLocationUpdates() {
if (fusedLocationClient == null) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity!!.applicationContext)
}
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.size > 0) {
val location = locationList[locationList.size - 1]
val latLng = LatLng(location.latitude, location.longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, defaultZoom))
}
}
}
fusedLocationClient?.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
locationRequest = LocationRequest()
locationRequest?.interval = 1800000
locationRequest?.fastestInterval = 1800000
locationRequest?.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
fusedLocationClient?.lastLocation?.addOnCompleteListener(Activity()) { task ->
if (task.isSuccessful && task.result != null) {
val latLong = LatLng(task.result!!.latitude, task.result!!.longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLong, defaultZoom))
}
}
}
private fun canAccessLocation(): Boolean {
return permissionsUtils.hasPermission(activity!!.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION)
}
}

因为你无法管理MapView(MapFragment(上显示的位置,而且它的标记不可点击(且可自定义(IMHO更好的方法是通过谷歌地图隐藏"默认"位置标记,就像Jozef:的回答一样

  1. 创建JSON文件src\main\res\raw\map_style.JSON如下:

[
{
featureType: "poi",
elementType: "labels",
stylers: [
{
visibility: "off"
}
]
}
]
  1. 将地图样式添加到GoogleMap

googleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.map_style));

然后-通过Google places API URL请求的Place Search获取附近的位置:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=<LAT_LNG>&types=point_of_interest&radius=<RADIUS_IN_METERS>&sensor=false&key=<YOUR_APP_KEY>

解析它并以编程方式将地图上所需的位置显示为可自定义和可点击的谷歌地图标记。这种方法不仅可以通过默认的onMarkerClick()处理标记点击,还可以管理地点的数量和类型、标记图标设计等。而且不需要每次用户点击地图时创建请求并处理其响应。

NB!附近的URL请求只返回20个位置,为了加载更多的数据,您应该使用响应的next_page_token标签中的字符串值,并通过pagetoken参数传递给下一个请求:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=<LAT_LNG>&types=point_of_interest&radius=<RADIUS_IN_METERS>&sensor=false&key=<YOUR_APP_KEY>&pagetoken=<TOKEN_FOR_NEXT_PAGE_FROM_next_page_token_TAG_OF_RESPONSE>

最新更新