Mapbox не может показать местоположение устройства - PullRequest
0 голосов
/ 13 марта 2020

У меня есть фрагмент с 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.

В чем здесь проблема? Любая помощь будет оценена.

1 Ответ

0 голосов
/ 13 марта 2020

"Но местоположение иногда не найдено, иногда это занимает очень много времени, даже службы определения местоположения готовы, прежде чем карта станет видимой при попытке использования устройств Android 9 и Android 7."

Звучит так, как будто устройство пытается получить местоположение от датчика GPS, но для его извлечения требуется много времени. С новыми устройствами и Android 10 была улучшена локализация, поэтому это может объяснить то, что вы видите.

Чтобы понять, что происходит, я бы порекомендовал реализовать Android FusedLocationProvider и сравните поведение с оболочкой из Mapbox SDK (locationComponent).

Также, пожалуйста, проверьте, действительно ли полученное с помощью Android 10 местоположение «snappy» действительно получено с датчика GPS, или это «просто» последнее известное местоположение, которое было кэшировано с помощью Android .

...