From 0aac0d2d64d01e884a5c6230e3a476014eabd4bd Mon Sep 17 00:00:00 2001 From: hicham Date: Sat, 30 Oct 2021 14:40:33 +0100 Subject: [PATCH] Show location updates when the app is active --- app/build.gradle | 1 + .../com/hicham/flowlifecycle/MainFragment.kt | 41 ++++++++++++++++++- .../com/hicham/flowlifecycle/MainViewModel.kt | 30 ++++++++++++++ app/src/main/res/layout/activity_main.xml | 6 +-- app/src/main/res/layout/fragment_main.xml | 10 +++++ 5 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/hicham/flowlifecycle/MainViewModel.kt diff --git a/app/build.gradle b/app/build.gradle index b378aea..3f4b2d8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,6 +38,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0" implementation "androidx.fragment:fragment-ktx:1.3.6" implementation 'com.google.android.gms:play-services-location:18.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.1' diff --git a/app/src/main/java/com/hicham/flowlifecycle/MainFragment.kt b/app/src/main/java/com/hicham/flowlifecycle/MainFragment.kt index 8f619fa..730deb4 100644 --- a/app/src/main/java/com/hicham/flowlifecycle/MainFragment.kt +++ b/app/src/main/java/com/hicham/flowlifecycle/MainFragment.kt @@ -1,12 +1,51 @@ package com.hicham.flowlifecycle +import android.Manifest +import android.content.pm.PackageManager.PERMISSION_GRANTED import android.os.Bundle import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.flowWithLifecycle +import androidx.lifecycle.lifecycleScope +import com.hicham.flowlifecycle.databinding.FragmentMainBinding +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch -class MainFragment: Fragment(R.layout.fragment_main) { +class MainFragment : Fragment(R.layout.fragment_main) { + private val viewModel: MainViewModel by viewModels() + + val requestPermissionLauncher = + registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted: Boolean -> + if (isGranted) { + viewModel.onLocationPermissionGranted() + } else { + // TODO + } + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + val binding = FragmentMainBinding.bind(view) + + val hasLocationPermission = + requireContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PERMISSION_GRANTED + + if (hasLocationPermission) { + viewModel.onLocationPermissionGranted() + } else { + requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) + } + + viewLifecycleOwner.lifecycleScope.launch { + viewModel.locationUpdates + .flowWithLifecycle(viewLifecycleOwner.lifecycle) + .onEach { binding.location.text = "${it.latitude} ${it.longitude}" } + .launchIn(this) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/hicham/flowlifecycle/MainViewModel.kt b/app/src/main/java/com/hicham/flowlifecycle/MainViewModel.kt new file mode 100644 index 0000000..d07e6ae --- /dev/null +++ b/app/src/main/java/com/hicham/flowlifecycle/MainViewModel.kt @@ -0,0 +1,30 @@ +package com.hicham.flowlifecycle + +import android.annotation.SuppressLint +import android.app.Application +import android.location.Location +import androidx.lifecycle.AndroidViewModel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flatMapLatest + +class MainViewModel(application: Application) : AndroidViewModel(application) { + private val locationObserver = LocationObserver(application) + + private val hasLocationPermission = MutableStateFlow(false) + + @SuppressLint("MissingPermission") + val locationUpdates: Flow = hasLocationPermission + .filter { it } + .flatMapLatest { locationObserver.observeLocationUpdates() } + + fun onLocationPermissionGranted() { + hasLocationPermission.value = true + } +} + +data class ViewState( + val location: Location, + val nearbyLocations: List +) \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 283fa4e..b1931c2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,13 +7,13 @@ tools:context=".MainActivity"> + app:layout_constraintTop_toTopOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 77d9ef6..313410d 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -1,6 +1,16 @@ + + \ No newline at end of file