Skip to content

Commit

Permalink
throw out coroutine-based location request flow :-(
Browse files Browse the repository at this point in the history
The reason why this does not (always) work is because coroutines may not survive the app being tabbed out and tabbed in again (e.g. going to location settings). So the flow cannot be handled by coroutines on the lifecycle scope of the activity/fragment (see #3967)
  • Loading branch information
westnordost committed Jan 6, 2023
1 parent f9f35fc commit 7d09e1a
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 167 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package de.westnordost.streetcomplete.screens

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.res.Configuration
import android.net.ConnectivityManager
Expand All @@ -20,6 +23,7 @@ import androidx.core.content.getSystemService
import androidx.core.text.parseAsHtml
import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import de.westnordost.streetcomplete.Prefs
import de.westnordost.streetcomplete.R
Expand Down Expand Up @@ -52,7 +56,7 @@ import de.westnordost.streetcomplete.util.ktx.hasLocationPermission
import de.westnordost.streetcomplete.util.ktx.isLocationEnabled
import de.westnordost.streetcomplete.util.ktx.toast
import de.westnordost.streetcomplete.util.location.LocationAvailabilityReceiver
import de.westnordost.streetcomplete.util.location.LocationRequester
import de.westnordost.streetcomplete.util.location.LocationRequestFragment
import de.westnordost.streetcomplete.util.parseGeoUri
import de.westnordost.streetcomplete.view.dialogs.RequestLoginDialog
import kotlinx.coroutines.launch
Expand All @@ -78,10 +82,16 @@ class MainActivity :
private val questPresetsSource: QuestPresetsSource by inject()
private val prefs: SharedPreferences by inject()

private val requestLocation = LocationRequester(this, this)

private var mainFragment: MainFragment? = null

private val requestLocationPermissionResultReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (!intent.getBooleanExtra(LocationRequestFragment.GRANTED, false)) {
toast(R.string.no_gps_no_quests, Toast.LENGTH_LONG)
}
}
}

private val elementEditsListener = object : ElementEditsSource.Listener {
override fun onAddedEdit(edit: ElementEdit) { lifecycleScope.launch { ensureLoggedIn() } }
override fun onSyncedEdit(edit: ElementEdit) {}
Expand All @@ -97,6 +107,11 @@ class MainActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

LocalBroadcastManager.getInstance(this).registerReceiver(
requestLocationPermissionResultReceiver,
IntentFilter(LocationRequestFragment.REQUEST_LOCATION_PERMISSION_RESULT)
)

lifecycle.addObserver(questAutoSyncer)
crashReportExceptionHandler.askUserToSendCrashReportIfExists(this)
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
Expand All @@ -108,6 +123,7 @@ class MainActivity :

mainFragment = supportFragmentManager.findFragmentById(R.id.map_fragment) as MainFragment?
if (savedInstanceState == null) {
supportFragmentManager.commit { add(LocationRequestFragment(), TAG_LOCATION_REQUEST) }
val hasShownTutorial = prefs.getBoolean(Prefs.HAS_SHOWN_TUTORIAL, false)
if (!hasShownTutorial && !userLoginStatusController.isLoggedIn) {
supportFragmentManager.commit {
Expand Down Expand Up @@ -332,15 +348,7 @@ class MainActivity :
/* ------------------------------- TutorialFragment.Listener -------------------------------- */

override fun onTutorialFinished() {
lifecycleScope.launch {
val hasLocation = requestLocation()
// if denied first time after exiting tutorial: ask again once (i.e. show rationale and ask again)
if (!hasLocation) {
requestLocation()
} else {
toast(R.string.no_gps_no_quests, Toast.LENGTH_LONG)
}
}
requestLocation()

prefs.edit { putBoolean(Prefs.HAS_SHOWN_TUTORIAL, true) }

Expand All @@ -353,6 +361,10 @@ class MainActivity :
}
}

private fun requestLocation() {
(supportFragmentManager.findFragmentByTag(TAG_LOCATION_REQUEST) as? LocationRequestFragment)?.startRequest()
}

/* ------------------------------------ Location listener ----------------------------------- */

private fun updateLocationAvailability(isAvailable: Boolean) {
Expand All @@ -364,6 +376,8 @@ class MainActivity :
}

companion object {
private const val TAG_LOCATION_REQUEST = "LocationRequestFragment"

// per application start settings
private var dontShowRequestAuthorizationAgain = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope
import de.westnordost.streetcomplete.ApplicationConstants
import de.westnordost.streetcomplete.Prefs
import de.westnordost.streetcomplete.R
Expand Down Expand Up @@ -75,6 +74,7 @@ import de.westnordost.streetcomplete.quests.IsShowingQuestDetails
import de.westnordost.streetcomplete.quests.LeaveNoteInsteadFragment
import de.westnordost.streetcomplete.quests.note_discussion.NoteDiscussionForm
import de.westnordost.streetcomplete.screens.HandlesOnBackPressed
import de.westnordost.streetcomplete.screens.MainActivity
import de.westnordost.streetcomplete.screens.main.bottom_sheet.CreateNoteFragment
import de.westnordost.streetcomplete.screens.main.bottom_sheet.IsCloseableBottomSheet
import de.westnordost.streetcomplete.screens.main.bottom_sheet.IsMapOrientationAware
Expand Down Expand Up @@ -106,7 +106,7 @@ import de.westnordost.streetcomplete.util.ktx.toast
import de.westnordost.streetcomplete.util.ktx.viewLifecycleScope
import de.westnordost.streetcomplete.util.location.FineLocationManager
import de.westnordost.streetcomplete.util.location.LocationAvailabilityReceiver
import de.westnordost.streetcomplete.util.location.LocationRequester
import de.westnordost.streetcomplete.util.location.LocationRequestFragment
import de.westnordost.streetcomplete.util.math.area
import de.westnordost.streetcomplete.util.math.enclosingBoundingBox
import de.westnordost.streetcomplete.util.math.enlargedBy
Expand Down Expand Up @@ -174,7 +174,6 @@ class MainFragment :
private val soundFx: SoundFx by inject()
private val prefs: SharedPreferences by inject()

private lateinit var requestLocation: LocationRequester
private lateinit var locationManager: FineLocationManager

private val binding by viewBinding(FragmentMainBinding::bind)
Expand Down Expand Up @@ -207,7 +206,6 @@ class MainFragment :
override fun onAttach(context: Context) {
super.onAttach(context)

requestLocation = LocationRequester(requireActivity(), this)
locationManager = FineLocationManager(context, this::onLocationChanged)

childFragmentManager.addFragmentOnAttachListener { _, fragment ->
Expand All @@ -216,6 +214,7 @@ class MainFragment :
is MainMenuButtonFragment -> mainMenuButtonFragment = fragment
}
}
childFragmentManager.commit { add(LocationRequestFragment(), TAG_LOCATION_REQUEST) }
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -728,7 +727,7 @@ class MainFragment :

when {
!binding.gpsTrackingButton.state.isEnabled -> {
lifecycleScope.launch { requestLocation() }
requestLocation()
}
!mapFragment.isFollowingPosition -> {
setIsFollowingPosition(true)
Expand All @@ -739,6 +738,10 @@ class MainFragment :
}
}

private fun requestLocation() {
(childFragmentManager.findFragmentByTag(TAG_LOCATION_REQUEST) as? LocationRequestFragment)?.startRequest()
}

private fun onClickCreateButton() {
showOverlayFormForNewElement()
}
Expand Down Expand Up @@ -1165,5 +1168,7 @@ class MainFragment :
companion object {
private const val BOTTOM_SHEET = "bottom_sheet"
private const val EDIT_HISTORY = "edit_history"

private const val TAG_LOCATION_REQUEST = "LocationRequestFragment"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class LocationAvailabilityReceiver(private val context: Context) {
)
LocalBroadcastManager.getInstance(context).registerReceiver(
requestLocationPermissionResultReceiver,
IntentFilter(LocationRequester.REQUEST_LOCATION_PERMISSION_RESULT)
IntentFilter(LocationRequestFragment.REQUEST_LOCATION_PERMISSION_RESULT)
)
}

Expand Down
Loading

0 comments on commit 7d09e1a

Please sign in to comment.