https://kotlinlang.org logo
#android
Title
# android
m

Manuel Lorenzo

07/27/2022, 9:40 AM
hi everybody! I have an activity that observes a Flow in my VM. The VM is in charge of obtaining the user location, and fetching the nearby places. However, when I rotate the device, I see that the API request being fired again from the VM, and it looks like permission related:
Copy code
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private val placesViewModel: PlacesViewModel by viewModels()
    private val locationPermissionRequest =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { permissionGranted ->
            when {
                permissionGranted -> placesViewModel.getNearbyPlaces(locationPermissionGiven = permissionGranted)
                else -> showLocationPermissionDeniedExplanationDialog(permissionGranted)
            }
        }
    // region Activity lifecycle

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        val adapter = PlacesAdapter()
        val recyclerView = findViewById<RecyclerView>(R.id.placesRecyclerView)
        val loadingProgressIndicator =
            findViewById<CircularProgressIndicator>(R.id.loadingProgressIndicator)
        recyclerView.adapter = adapter
        lifecycleScope.launch {
            observeChanges(loadingProgressIndicator, adapter)
        }
        checkForLocationPermissionsAndHandleResult()
    }

    private suspend fun observeChanges(
        loadingProgressIndicator: CircularProgressIndicator,
        adapter: PlacesAdapter
    ) {
        placesViewModel.uiState.collect {
            when {
                it.loading -> loadingProgressIndicator.visibility = View.VISIBLE
                it.places?.isNotEmpty() == true -> {
                    loadingProgressIndicator.visibility = View.GONE
                    adapter.submitList(it.places)
                }
            }
        }
    }

    // endregion

    // region Location permission related methods

    /**
     * Shows a dialog explaining that the [Manifest.permission.ACCESS_FINE_LOCATION] has been denied
     * and that a default location will be used in order to fetch the nearby places.
     */
    private fun showLocationPermissionDeniedExplanationDialog(permissionGranted: Boolean) {
        AlertDialog.Builder(this)
            .setMessage(getString(R.string.permission_denied_dialog_message))
            .setPositiveButton(getString(R.string.permission_denied_dialog_positive_button_text)) { _, _ ->
                placesViewModel.getNearbyPlaces(locationPermissionGiven = permissionGranted)
            }
            .show()
    }

    /**
     * Check for the [Manifest.permission.ACCESS_FINE_LOCATION] permission.
     * If the permission is granted, fetch the user's nearby places with [placesViewModel.getNearbyPlaces()].
     * Otherwise, show a dialog explaining that because of denying the location permission, a default location will be used.
     */
    private fun checkForLocationPermissionsAndHandleResult() {
        when {
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED -> {
                placesViewModel.getNearbyPlaces(locationPermissionGiven = true)
            }
            shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) -> {
                AlertDialog.Builder(this)
                    .setMessage(getString(R.string.permission_dialog_message_text))
                    .setNegativeButton(getString(R.string.permission_dialog_negative_button_text)) { dialog, _ ->
                        dialog.dismiss()
                        placesViewModel.getNearbyPlaces(locationPermissionGiven = false)
                    }
                    .setPositiveButton(getString(R.string.permission_dialog_positive_button_text)) { dialog, _ ->
                        locationPermissionRequest.launch(Manifest.permission.ACCESS_FINE_LOCATION)
                        dialog.dismiss()
                        placesViewModel.getNearbyPlaces(locationPermissionGiven = true)
                    }.show()
            }
            else -> {
                locationPermissionRequest.launch(Manifest.permission.ACCESS_FINE_LOCATION)
            }
        }
    }
    // endregion
}
😶 1
🧵 2
3 Views