Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const val CANCEL_TRACKING_TAG = "cancelTag"
- @AndroidEntryPoint
- class TrackingFragment : Fragment() {
- private val viewModel: MainViewModel by viewModels()
- private var _binding: FragmentTrackingBinding? = null
- private val binding get() = _binding!!
- private var map: GoogleMap? = null
- private var isTracking = false
- private var pathPoints = mutableListOf<Polyline>()
- private var curTimeInMillis = 0L
- private var menu: Menu? = null
- @set:Inject
- var weight = 80f
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentTrackingBinding.inflate(inflater, container, false)
- setHasOptionsMenu(true)
- binding.mapView.onCreate(savedInstanceState)
- return binding.root
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- binding.mapView.getMapAsync {
- map = it
- addAllPolylines()
- }
- binding.btnToggleRun.setOnClickListener {
- toggleRun()
- }
- binding.btnFinishRun.setOnClickListener {
- zoomToSeeWholeTrack()
- endRunAndSaveToDb()
- }
- subscribeToObservers()
- if (savedInstanceState != null) {
- val cancelTrackingFragment =
- parentFragmentManager.findFragmentByTag(CANCEL_TRACKING_TAG)
- as CancelTrackingFragment?
- cancelTrackingFragment?.yesListener {
- stopRun()
- }
- }
- }
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
- super.onCreateOptionsMenu(menu, inflater)
- inflater.inflate(R.menu.tracking_menu, menu)
- this.menu = menu
- }
- override fun onPrepareOptionsMenu(menu: Menu) {
- super.onPrepareOptionsMenu(menu)
- if (curTimeInMillis > 0L) {
- this.menu?.getItem(0)?.isVisible = true
- }
- }
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.menu_cancelTracking -> showCancelTrackingDialog()
- }
- return super.onOptionsItemSelected(item)
- }
- private fun showCancelTrackingDialog() {
- CancelTrackingFragment().apply {
- yesListener {
- stopRun()
- }
- }.show(parentFragmentManager, CANCEL_TRACKING_TAG)
- }
- private fun stopRun() {
- sendCommandToService(ACTION_STOP_SERVICE)
- findNavController().navigate(R.id.action_trackingFragment_to_runFragment)
- }
- private fun subscribeToObservers() {
- TrackingService.isTracking.observe(viewLifecycleOwner) {
- updateTracking(it)
- }
- TrackingService.pathPoints.observe(viewLifecycleOwner) {
- pathPoints = it
- addLatestPolyline()
- moveCameraToUser()
- }
- TrackingService.timeRunInMillis.observe(viewLifecycleOwner) {
- curTimeInMillis = it
- val formattedTime = TrackingUtility.getFormattedStopWatchTime(curTimeInMillis, true)
- binding.tvTimer.text = formattedTime
- }
- }
- private fun toggleRun() {
- if (isTracking) {
- menu?.getItem(0)?.isVisible = true
- sendCommandToService(ACTION_PAUSE_SERVICE)
- } else sendCommandToService(ACTION_START_OR_RESUME_SERVICE)
- }
- private fun updateTracking(isTracking: Boolean) {
- this.isTracking = isTracking
- if (!isTracking && curTimeInMillis > 0L) {
- binding.apply {
- btnToggleRun.text = "Start"
- btnFinishRun.visibility = View.VISIBLE
- }
- } else if (isTracking) {
- binding.apply {
- btnToggleRun.text = "Stop"
- menu?.getItem(0)?.isVisible = true
- btnFinishRun.visibility = View.GONE
- }
- }
- }
- private fun moveCameraToUser() {
- if (pathPoints.isNotEmpty() && pathPoints.last().isNotEmpty()) {
- map?.animateCamera(
- CameraUpdateFactory.newLatLngZoom(
- pathPoints.last().last(),
- MAP_ZOOM
- )
- )
- }
- }
- private fun zoomToSeeWholeTrack() {
- val bounds = LatLngBounds.Builder()
- for (polyline in pathPoints)
- for (positon in polyline) {
- bounds.include(positon)
- }
- map?.moveCamera(
- CameraUpdateFactory.newLatLngBounds(
- bounds.build(),
- binding.mapView.width,
- binding.mapView.height,
- (binding.mapView.height * 0.05f).toInt()
- )
- )
- }
- private fun addAllPolylines() {
- for (polyline in pathPoints) {
- val polylineOptions = PolylineOptions()
- .color(POLYLINE_COLOR)
- .width(POLYLINE_WIDTH)
- .addAll(polyline)
- map?.addPolyline(polylineOptions)
- }
- }
- private fun addLatestPolyline() {
- if (pathPoints.isNotEmpty() && pathPoints.last().size > 1) {
- val preLastLatLng = pathPoints.last()[pathPoints.last().size - 2]
- val lastLatLng = pathPoints.last().last()
- val polylineOptions = PolylineOptions()
- .color(POLYLINE_COLOR)
- .width(POLYLINE_WIDTH)
- .add(preLastLatLng, lastLatLng)
- map?.addPolyline(polylineOptions)
- }
- }
- private fun endRunAndSaveToDb() {
- map?.snapshot { bitmap ->
- var distanceInMiters = 0
- for (polyline in pathPoints) {
- distanceInMiters += TrackingUtility.calculatePolylineLength(polyline).toInt()
- }
- val avgSpeed =
- round((distanceInMiters / 1000f) / (curTimeInMillis / 1000f / 60 / 60) * 10) / 10f
- val dateTimestamp = Calendar.getInstance().timeInMillis
- val caloriesBurned = ((distanceInMiters / 1000f) * weight).toInt()
- val run = Run(
- bitmap,
- dateTimestamp,
- avgSpeed,
- distanceInMiters,
- curTimeInMillis,
- caloriesBurned
- )
- viewModel.insertRun(run)
- Snackbar.make(
- requireActivity().findViewById(R.id.rootView),
- "Run saved successfully",
- Snackbar.LENGTH_LONG
- ).show()
- }
- stopRun()
- }
- override fun onResume() {
- super.onResume()
- binding.mapView.onResume()
- }
- override fun onStart() {
- super.onStart()
- binding.mapView.onStart()
- }
- override fun onPause() {
- super.onPause()
- binding.mapView.onPause()
- }
- override fun onStop() {
- super.onStop()
- binding.mapView.onStop()
- }
- override fun onLowMemory() {
- super.onLowMemory()
- binding.mapView.onLowMemory()
- }
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- binding.mapView.onSaveInstanceState(outState)
- }
- private fun sendCommandToService(action: String) =
- Intent(requireContext(), TrackingService::class.java).also {
- it.action = action
- requireContext().startService(it)
- }
- override fun onDestroyView() {
- super.onDestroyView()
- binding.mapView.onDestroy()
- }
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement