Невозможно правильно инициализировать Mapbox в приложении Android.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Невозможно правильно инициализировать Mapbox в приложении Android.

Сообщение Anonymous »

Я пытаюсь использовать Mapbox в своем приложении, но у меня возникли некоторые проблемы. Мой код выглядит следующим образом:
HomeFragment:

Код: Выделить всё

@AndroidEntryPoint
class HomeFragment : Fragment() {

private var _binding: FragmentHomeBinding? = null
private val binding: FragmentHomeBinding get() = _binding!!

private lateinit var onBackPressedCallback: OnBackPressedCallback

private val viewModel: HomeViewModel by viewModels()

private lateinit var map: GoogleMap
private lateinit var mapView: MapView
private lateinit var locationComponentPlugin: LocationComponentPlugin

private val markersManager = MarkersManager()
private val routesManager = RoutesManager()

private val onIndicatorBearingChangedListener = OnIndicatorBearingChangedListener {
mapView.mapboxMap.setCamera(CameraOptions.Builder().bearing(it).build())
}

private val onIndicatorPositionChangedListener = OnIndicatorPositionChangedListener {
mapView.mapboxMap.setCamera(CameraOptions.Builder().center(it).build())
mapView.gestures.focalPoint = mapView.mapboxMap.pixelForCoordinate(it)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MapboxOptions.accessToken = requireContext().getString(R.string.mapbox_access_token)
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupMap()
setupView()
setupOnBackPress()
setupViewModelSubscriptions()
}

override fun onResume() {
super.onResume()

val missingPermissions = PermissionUtils.checkPermissions(requireContext(), neededPermissions)
if (missingPermissions.isNotEmpty()) {
findNavController()
.navigate(R.id.action_homeFragment_to_missingPermissionsFragment)
}
}

override fun onDestroyView() {
super.onDestroyView()
onBackPressedCallback.remove()
_binding = null
}

private fun setupView() {
binding.btnManageCars.setOnClickListener {
findNavController().navigate(R.id.action_homeFragment_to_manageCarsFragment)
}
binding.btnPlaceCar.setOnClickListener {
onPlaceClicked()
}
binding.btnStartNavi.setOnClickListener {
viewModel.onEvent(HomeEvent.StartNavigation)
}
binding.btnCancelNavi.setOnClickListener {
viewModel.onEvent(HomeEvent.CancelNavigation)
}
}

private fun setupMap() {
mapView = MapView(requireContext())
mapView.mapboxMap.loadStyle(Style.STANDARD)
initLocationComponent()
}

private fun initLocationComponent() {
locationComponentPlugin = mapView.location
locationComponentPlugin.updateSettings {
puckBearing = PuckBearing.COURSE
puckBearingEnabled = true
enabled = true
locationPuck = LocationPuck2D(
bearingImage = ImageHolder.from(com.mapbox.maps.R.drawable.mapbox_user_puck_icon),
shadowImage = ImageHolder.from(com.mapbox.maps.R.drawable.mapbox_user_icon_shadow),
scaleExpression = interpolate {
linear()
zoom()
stop {
literal(0.0)
literal(0.6)
}
stop {
literal(20.0)
literal(1.0)
}
}.toJson()
)
}

locationComponentPlugin.addOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener)
locationComponentPlugin.addOnIndicatorBearingChangedListener(onIndicatorBearingChangedListener)
}

private fun setupOnBackPress() {
onBackPressedCallback = object :  OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
this.isEnabled = false
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}

requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, onBackPressedCallback)
}

private fun setupViewModelSubscriptions() {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.lastLocation.collectLatest { location ->
location?.let {
updateUserLocation(it)
}
}
}
launch {
viewModel.oneTimeEvent.collect { event ->
manageOneTimeEvent(event)
}
}
}
}

private fun updateUserLocation(location: Location) {
mapView.mapboxMap.setCamera(
CameraOptions.Builder()
.center(Point.fromLngLat(location.longitude, location.latitude))
.zoom(25.0)
.build()
)
}
}
HomeViewModel:

Код: Выделить всё

@HiltViewModel
class HomeViewModel @Inject constructor(
private val startLocationUpdatesUseCase: StartLocationUpdatesUseCase,
private val stopLocationUpdatesUseCase: StopLocationUpdatesUseCase,
private val getCurrentLocationUseCase: GetCurrentLocationUseCase,
private val getAllCarsUseCase: GetAllCarsUseCase,
private val getPlacedCarsUseCase: GetPlacedCarsUseCase,
private val startNavigationUseCase: StartNavigationUseCase,
private val setCarLocationUseCase: SetCarLocationUseCase,
private val removeCarLocationUseCase: RemoveCarLocationUseCase,
) : ViewModel() {

val lastLocation: StateFlow = getCurrentLocationUseCase()

private val _uiState = MutableStateFlow(HomeState())
val uiState: StateFlow = _uiState.asStateFlow()

private val _oneTimeEvent = MutableSharedFlow()
val oneTimeEvent: SharedFlow = _oneTimeEvent.asSharedFlow()

init {
startLocationUpdatesUseCase()
onEvent(HomeEvent.GetUserCars)
onEvent(HomeEvent.GetPlacedCars)
}
...
...
...
}
Примеры использования:

Код: Выделить всё

class StartLocationUpdatesUseCase@Inject constructor(
private val repository: LocationRepository
) {

operator fun invoke() {
repository.startLocationUpdates()
}

}

class StopLocationUpdatesUseCase @Inject constructor(
private val repository: LocationRepository
) {

operator fun invoke() = repository.stopLocationUpdates()

}

class GetCurrentLocationUseCase @Inject constructor(
private val repository: LocationRepository
) {

operator fun invoke(): StateFlow = repository.currentLocation

}
Репозиторий:

Код: Выделить всё

class LocationRepositoryImpl @Inject constructor(
private val deviceLocationProvider: DeviceLocationProvider
) : LocationRepository {

private val _currentLocation = MutableStateFlow(null)
override val currentLocation: StateFlow  = _currentLocation.asStateFlow()

private val locationObserver = LocationObserver { locations ->
_currentLocation.value = locations.lastOrNull()
}

override fun startLocationUpdates() {
deviceLocationProvider.addLocationObserver(locationObserver)
}

override fun stopLocationUpdates() {
deviceLocationProvider.removeLocationObserver(locationObserver)
}
}
И модуль местоположения

Код: Выделить всё

@Module
@InstallIn(SingletonComponent::class)
class LocationModule {

@Provides
fun provideDeviceLocationProvider(): DeviceLocationProvider {
val locationService = LocationServiceFactory.getOrCreate()
val request = LocationProviderRequest.Builder()
.interval(IntervalSettings.Builder().interval(1000L).minimumInterval(1000L).maximumInterval(5000L).build())
.displacement(0f)
.accuracy(AccuracyLevel.HIGHEST)
.build()

val result = locationService.getDeviceLocationProvider(request)
if (result.isValue) {
return result.value!!
} else {
throw IllegalStateException("Cannot obtain DeviceLocationProvider: ${result.error?.message ?: "Unknown error"}")
}
}

}
По неизвестной причине я не могу видеть пользователя на карте или даже переключать камеру при обновлении местоположения. Текущее поведение таково, что приложение показывает карту при запуске, и ничего не меняется. Я даже могу изменить стили карты, но это тоже ничего не даст. Кто-нибудь знает, в чем может быть проблема?

Подробнее здесь: https://stackoverflow.com/questions/790 ... pplication
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»