У меня есть фрагмент с Mapbox, и я хочу отобразить местоположение устройства на нем.
class SampleMapFragment : Fragment(), PermissionsListener {
private lateinit var binding: FragmentExploreBinding
@Inject
lateinit var permissionsManager: PermissionsManager
private lateinit var mapboxMap: MapboxMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Mapbox.getInstance(requireContext().applicationContext, getString(R.string.mapbox_token))
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (!::binding.isInitialized) {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_explore,
container,
false
)
binding.lifecycleOwner = this
binding.mapView.onCreate(savedInstanceState)
setUpMap()
}
return binding.root
}
private fun setUpMap() {
binding.mapView.getMapAsync { mapboxMap ->
this.mapboxMap = mapboxMap
mapboxMap.setStyle(Style.MAPBOX_STREETS) { loadedMapStyle ->
starLocationTracking(loadedMapStyle)
}
}
}
private fun starLocationTracking(loadedMapStyle: Style) {
if (!PermissionsManager.areLocationPermissionsGranted(requireContext())) {
permissionsManager.requestLocationPermissions(requireActivity())
return
}
initLocationComponent(loadedMapStyle)
}
private fun initLocationComponent(loadedMapStyle: Style) {
val customLocationComponentOptions = LocationComponentOptions.builder(requireActivity())
.elevation(5f)
.accuracyAlpha(.6f)
.accuracyColor(Color.RED)
.build()
val locationComponentActivationOptions = LocationComponentActivationOptions.builder(
requireActivity(),
loadedMapStyle
)
.locationComponentOptions(customLocationComponentOptions)
.build()
mapboxMap.locationComponent.apply {
activateLocationComponent(locationComponentActivationOptions)
isLocationComponentEnabled = true
renderMode = RenderMode.COMPASS
cameraMode = CameraMode.TRACKING
}
}
override fun onExplanationNeeded(permissionsToExplain: MutableList<String>?) {
// TODO some explanation can be shown here
}
override fun onPermissionResult(granted: Boolean) {
if (granted) mapboxMap.getStyle { loadedStyle -> starLocationTracking(loadedStyle) }
//else TODO some explanation can be shown here
}
fun onMapBoxRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) = permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults)
override fun onStart() {
super.onStart()
binding.mapView.onStart()
}
override fun onResume() {
super.onResume()
binding.mapView.onResume()
}
override fun onPause() {
super.onPause()
binding.mapView.onPause()
}
override fun onStop() {
super.onStop()
binding.mapView.onStop()
}
override fun onDestroy() {
super.onDestroy()
releaseMapResources()
releasePermissionsManagerListener()
}
private fun releaseMapResources() {
binding.mapView.onDestroy()
}
private fun releasePermissionsManagerListener() {
permissionsManager.listener = null
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
binding.mapView.onLowMemory()
}
}
Я протестировал реализацию выше с 2 реальными устройствами и 1 эмулятором. Решение отлично работает с устройством Android 10. Местоположение пользователя найдено, даже после закрытия служб определения местоположения и открытия его снова после отображения карты.
Но местоположение иногда не найдено, иногда это занимает очень много времени, даже службы определения местоположения готовы до карты отображается при попытке использования устройств Android 9 и Android 7.
В чем здесь проблема? Любая помощь будет оценена.