Skip to content

Instantly share code, notes, and snippets.

@vasmarfas
Last active February 4, 2024 23:57
Show Gist options
  • Save vasmarfas/56ae6912ee83a5ec37aa90e05dc38b9e to your computer and use it in GitHub Desktop.
Save vasmarfas/56ae6912ee83a5ec37aa90e05dc38b9e to your computer and use it in GitHub Desktop.
package ru.vasmarfas.m19_location
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.LocationSource
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import ru.vasmarfas.m19_location.databinding.FragmentMapsBinding
class MapsFragment : Fragment() {
private var _binding: FragmentMapsBinding? = null
private val binding get() = _binding!!
private var locationListener: LocationSource.OnLocationChangedListener? = null
private val viewModel: MapsViewModel by viewModels()
private var myGoogleMap: GoogleMap? = null
var lastLocation: Location? = null
// var listOfMarkers = mutableListOf<Marker>()
var AllMarkers: MutableList<Marker> = ArrayList()
private fun removeAllMarkers() {
for (mLocationMarker in AllMarkers) {
mLocationMarker.remove()
}
AllMarkers.clear()
}
private var landmarksJob: Job? = null
private lateinit var fusedClient: FusedLocationProviderClient
private val launcher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { map ->
if (map.values.isNotEmpty() && map.values.all { it }) {
startLocation()
} else {
for (permission in map) {
if (!permission.value) {
ActivityResultContracts.RequestPermission()
}
}
}
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
super.onLocationResult(result)
result.lastLocation?.let { location ->
locationListener?.onLocationChanged(location)
if (lastLocation!= null) {
if (location.latitude != lastLocation!!.latitude && location.longitude != lastLocation!!.longitude) {
myGoogleMap?.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(location.latitude,location.longitude),
15f
)
)
Log.d("MapFragm", location.toString())
lastLocation = location
removeAllMarkers()
viewModel.loadLandmarks(location.longitude, location.latitude, 10000.0)
landmarksJob?.cancel()
landmarksJob = viewModel.landmarks.onEach {
Log.d("MapFragment", it.toString())
for (item in it) {
val itemPoint = LatLng(item.geometry.coordinates[1], item.geometry.coordinates[0])
val tempMarker = myGoogleMap?.addMarker(MarkerOptions().position(itemPoint).title(item.properties.name))
if (tempMarker != null) {
AllMarkers.add(tempMarker)
}
}
Log.d("Marker List added", AllMarkers.toString())
// googleMap.addMarker(MarkerOptions().position())
}.launchIn(lifecycleScope)
}
} else {
myGoogleMap?.animateCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(location.latitude,location.longitude),
15f
)
)
lastLocation = location
viewModel.loadLandmarks(location.longitude, location.latitude, 10000.0)
}
}
// binding.testText.text = result.lastLocation.toString()
}
}
@SuppressLint("MissingPermission")
private fun startLocation() {
val request = LocationRequest.create()
.setInterval(1_000)
.setPriority(Priority.PRIORITY_HIGH_ACCURACY)
fusedClient.requestLocationUpdates(
request,
locationCallback,
Looper.getMainLooper()
)
}
private fun checkPermissions() {
if (REQUIRED_PERMISSIONS.all { permission ->
val testVar = ContextCompat.checkSelfPermission(requireContext(), permission)
testVar == PackageManager.PERMISSION_GRANTED
}) {
startLocation()
} else {
launcher.launch(REQUIRED_PERMISSIONS)
}
}
companion object {
private val REQUIRED_PERMISSIONS: Array<String> = arrayOf(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION
)
}
override fun onStart() {
super.onStart()
checkPermissions()
}
override fun onStop() {
super.onStop()
fusedClient.removeLocationUpdates(locationCallback)
}
private val mapCallback = OnMapReadyCallback { googleMap ->
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera.
* In this case, we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to
* install it inside the SupportMapFragment. This method will only be triggered once the
* user has installed Google Play services and returned to the app.
*/
myGoogleMap = googleMap
googleMap.isMyLocationEnabled = true
with(googleMap.uiSettings) {
this.isZoomControlsEnabled = true
this.isMyLocationButtonEnabled = true
}
googleMap.setLocationSource(object : LocationSource {
override fun activate(p0: LocationSource.OnLocationChangedListener) {
locationListener = p0
}
override fun deactivate() {
locationListener = null
}
})
// viewModel.landmarks.onEach {
// Log.d("MapFragment", it.toString())
// for (item in it) {
// val itemPoint = LatLng(item.geometry.coordinates[1], item.geometry.coordinates[0])
// googleMap.addMarker(MarkerOptions().position(itemPoint).title(item.properties.name))
// }
// googleMap.addMarker(MarkerOptions().position())
// }.launchIn(lifecycleScope)
// viewLifecycleOwner.lifecycleScope.launch() {
// viewModel.landmarks.collect { landmarks ->
// Log.d("Maps_FRAGMENT", landmarks.toString())
// for (item in landmarks) {
// val itemPoint = LatLng(item.geometry.coordinates[1], item.geometry.coordinates[0])
// googleMap.addMarker(MarkerOptions().position(itemPoint).title(item.properties.name))
// }
//
// // здесь обновите ваш UI с использованием полученных данных landmarks
// }
// }
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
fusedClient = LocationServices.getFusedLocationProviderClient(requireActivity())
_binding = FragmentMapsBinding.inflate(inflater, container, false)
// Inflate the layout for this fragment
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(mapCallback)
// viewLifecycleOwner.lifecycleScope.launch {
// viewModel.landmarks.collect { landmarks ->
// Log.d("Maps_FRAGMENT", landmarks.toString())
// // здесь обновите ваш UI с использованием полученных данных landmarks
// }
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment