diff options
| author | jacquarg <guillaume.jacquart@hoodbrains.com> | 2021-11-07 22:43:32 +0100 |
|---|---|---|
| committer | jacquarg <guillaume.jacquart@hoodbrains.com> | 2021-11-12 13:13:23 +0100 |
| commit | 5891ac8ea718dcb40014f5a90d2672f902eb6c55 (patch) | |
| tree | 083007df227f0c91fed1c48ed81471074dae853f /app/src/main/java/foundation/e/privacycentralapp/features | |
| parent | 2ea0e99f1bcec61e1a94bb7c35605fca49c53d1c (diff) | |
| download | advanced-privacy-5891ac8ea718dcb40014f5a90d2672f902eb6c55.tar.gz | |
Update fake location
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
5 files changed, 144 insertions, 304 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt index 5185737..39b6138 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt @@ -56,7 +56,7 @@ class DashboardFeature( val totalGraph: Int? = null, // val graphData val trackersCount: Int? = null, - val dayTrackersCount: Int? = null, + val activeTrackersCount: Int? = null, val dayStatistics: List<Int>? = null ) diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt index b16af28..7c6a715 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt @@ -18,17 +18,17 @@ package foundation.e.privacycentralapp.features.location import android.util.Log -import com.mapbox.mapboxsdk.geometry.LatLng import foundation.e.flowmvi.Actor import foundation.e.flowmvi.Reducer import foundation.e.flowmvi.SingleEventProducer import foundation.e.flowmvi.feature.BaseFeature import foundation.e.privacycentralapp.domain.entities.LocationMode -import foundation.e.privacycentralapp.dummy.CityDataSource -import foundation.e.privacycentralapp.dummy.DummyDataSource -import foundation.e.privacycentralapp.dummy.Location +import foundation.e.privacycentralapp.domain.usecases.FakeLocationStateUseCase +import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.merge // Define a state machine for Fake location feature class FakeLocationFeature( @@ -46,7 +46,10 @@ class FakeLocationFeature( singleEventProducer ) { data class State( - val location: Location + val isEnabled: Boolean, + val mode: LocationMode, + val specificLatitude: Float? = null, + val specificLongitude: Float? = null ) sealed class SingleEvent { @@ -57,153 +60,97 @@ class FakeLocationFeature( } sealed class Action { + object Init : Action() // Action which is triggered everytime the location is updated. - data class UpdateLocationAction(val latLng: LatLng) : Action() - object UseRealLocationAction : Action() - data class UseRandomLocationAction( - val cities: Array<String> - ) : Action() { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as UseRandomLocationAction - - if (!cities.contentEquals(other.cities)) return false + //data class UpdateLocationAction(val latLng: LatLng) : Action() - return true - } - - override fun hashCode(): Int { - return cities.contentHashCode() - } - } - - object UseSpecificLocationAction : Action() - data class SetCustomFakeLocationAction( - val latitude: Double, - val longitude: Double - ) : Action() + object UseRealLocationAction : Action() + object UseRandomLocationAction : Action() + data class SetSpecificLocationAction( + val latitude: Float, + val longitude: Float) : Action() } sealed class Effect { - data class LocationUpdatedEffect(val latitude: Double, val longitude: Double) : Effect() - object RealLocationSelectedEffect : Effect() - object RandomLocationSelectedEffect : Effect() - object SpecificLocationSelectedEffect : Effect() - object SpecificLocationSavedEffect : Effect() + data class QuickPrivacyUpdatedEffect(val isEnabled: Boolean): Effect() + data class LocationModeUpdatedEffect( + val mode: LocationMode, + val latitude: Float? = null, + val longitude: Float? = null) : Effect() data class ErrorEffect(val message: String) : Effect() + object QuickPrivacyDisabledWarningEffect : Effect() } companion object { fun create( initialState: State = State( - Location( - LocationMode.REAL_LOCATION, - 0.0, - 0.0 - ) + isEnabled = false, + mode = LocationMode.REAL_LOCATION ), - coroutineScope: CoroutineScope, - locationApi: LocationApiDelegate + getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, + fakeLocationStateUseCase: FakeLocationStateUseCase, + coroutineScope: CoroutineScope ) = FakeLocationFeature( initialState, coroutineScope, reducer = { state, effect -> when (effect) { - Effect.RandomLocationSelectedEffect -> state.copy( - location = state.location.copy( - mode = LocationMode.RANDOM_LOCATION - ) - ) - Effect.RealLocationSelectedEffect -> state.copy( - location = state.location.copy( - mode = LocationMode.REAL_LOCATION - ) - ) - is Effect.ErrorEffect, Effect.SpecificLocationSavedEffect -> state - is Effect.LocationUpdatedEffect -> state.copy( - location = state.location.copy( - latitude = effect.latitude, - longitude = effect.longitude - ) - ) - is Effect.SpecificLocationSelectedEffect -> state.copy( - location = state.location.copy( - mode = LocationMode.CUSTOM_LOCATION - ) - ) + is Effect.QuickPrivacyUpdatedEffect -> state.copy(isEnabled = effect.isEnabled) + is Effect.LocationModeUpdatedEffect -> state.copy( + mode = effect.mode, + specificLatitude = effect.latitude, + specificLongitude = effect.longitude) + + is Effect.ErrorEffect, + Effect.QuickPrivacyDisabledWarningEffect -> state } }, - actor = { _, action -> + actor = { state, action -> when (action) { - is Action.UpdateLocationAction -> flowOf( - Effect.LocationUpdatedEffect( - action.latLng.latitude, - action.latLng.longitude - ) - ) - is Action.SetCustomFakeLocationAction -> { - val location = Location( - LocationMode.CUSTOM_LOCATION, - action.latitude, - action.longitude - ) - locationApi.setFakeLocation(action.latitude, action.longitude) - val success = DummyDataSource.setLocationMode( - LocationMode.CUSTOM_LOCATION, - location - ) - if (success) { - flowOf( - Effect.SpecificLocationSavedEffect + is Action.Init -> merge( + getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map { Effect.QuickPrivacyUpdatedEffect(it) }, + flowOf(Effect.LocationModeUpdatedEffect(fakeLocationStateUseCase.getLocationMode()))) + + // is Action.UpdateLocationAction -> flowOf( + // Effect.LocationUpdatedEffect( + // action.latLng.latitude, + // action.latLng.longitude + // ) + // ) + + is Action.SetSpecificLocationAction -> { + if (state.isEnabled) { + fakeLocationStateUseCase.setSpecificLocation( + action.latitude, + action.longitude ) - } else { flowOf( - Effect.ErrorEffect("Couldn't select location") + Effect.LocationModeUpdatedEffect( + mode = LocationMode.SPECIFIC_LOCATION, + latitude = action.latitude, + longitude = action.longitude + ) ) - } + } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) } is Action.UseRandomLocationAction -> { - val randomCity = CityDataSource.getRandomCity(action.cities) - locationApi.setFakeLocation(randomCity.latitude, randomCity.longitude) - val success = DummyDataSource.setLocationMode( - LocationMode.RANDOM_LOCATION, - randomCity.toRandomLocation() - ) - if (success) { - flowOf( - Effect.RandomLocationSelectedEffect - ) - } else { - flowOf( - Effect.ErrorEffect("Couldn't select location") - ) - } + if (state.isEnabled) { + fakeLocationStateUseCase.setRandomLocation() + flowOf(Effect.LocationModeUpdatedEffect(LocationMode.RANDOM_LOCATION)) + } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) } is Action.UseRealLocationAction -> { - locationApi.startRealLocation() - val success = DummyDataSource.setLocationMode(LocationMode.REAL_LOCATION) - if (success) { - flowOf( - Effect.RealLocationSelectedEffect - ) - } else { - flowOf( - Effect.ErrorEffect("Couldn't select location") - ) - } - } - is Action.UseSpecificLocationAction -> { - flowOf(Effect.SpecificLocationSelectedEffect) + if (state.isEnabled) { + fakeLocationStateUseCase.stopFakeLocation() + flowOf(Effect.LocationModeUpdatedEffect(LocationMode.REAL_LOCATION)) + } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) } } }, singleEventProducer = { _, _, effect -> when (effect) { - Effect.RandomLocationSelectedEffect -> SingleEvent.RandomLocationSelectedEvent - Effect.SpecificLocationSavedEffect -> SingleEvent.SpecificLocationSavedEvent - Effect.RealLocationSelectedEffect -> SingleEvent.RealLocationSelectedEvent + Effect.QuickPrivacyDisabledWarningEffect -> + SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities") is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message) else -> null } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt index bdc405e..0f69808 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt @@ -28,7 +28,6 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView -import android.widget.RadioButton import android.widget.Toast import androidx.annotation.NonNull import androidx.core.view.isVisible @@ -62,6 +61,7 @@ import foundation.e.privacycentralapp.common.NavToolbarFragment import foundation.e.privacycentralapp.databinding.FragmentFakeLocationBinding import foundation.e.privacycentralapp.domain.entities.LocationMode import foundation.e.privacycentralapp.extensions.viewModelProviderFactoryOf +import foundation.e.privacycentralapp.features.location.FakeLocationFeature.Action import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive @@ -93,11 +93,13 @@ class FakeLocationFragment : private var inputJob: Job? = null + private var displayedLocation: Pair<Float, Float>? = null // Callback which updates the map in realtime. private val locationChangeCallback: LocationEngineCallback<LocationEngineResult> = object : LocationEngineCallback<LocationEngineResult> { override fun onSuccess(result: LocationEngineResult?) { result?.lastLocation?.let { + displayedLocation = it.latitude.toFloat() to it.longitude.toFloat() mapboxMap.locationComponent.forceLocationUpdate( LocationUpdate.Builder().location(it).animationDuration(100) .build() @@ -114,16 +116,16 @@ class FakeLocationFragment : } // Only update location when location mode is set to real location or random location. // It basically triggers a UI update. - if (viewModel.fakeLocationFeature.state.value.location.mode != LocationMode.CUSTOM_LOCATION) { - viewModel.submitAction( - FakeLocationFeature.Action.UpdateLocationAction( - LatLng( - it.latitude, - it.longitude - ) - ) - ) - } + // if (viewModel.fakeLocationFeature.state.value.location.mode != LocationMode.SPECIFIC_LOCATION) { + // viewModel.submitAction( + // FakeLocationFeature.Action.UpdateLocationAction( + // LatLng( + // it.latitude, + // it.longitude + // ) + // ) + // ) + // } } } @@ -148,29 +150,13 @@ class FakeLocationFragment : lifecycleScope.launchWhenStarted { viewModel.fakeLocationFeature.singleEvents.collect { event -> when (event) { - is FakeLocationFeature.SingleEvent.RandomLocationSelectedEvent -> { - displayToast("Random location selected") - hoveringMarker?.visibility = View.GONE - isCameraMoved = false - } - is FakeLocationFeature.SingleEvent.SpecificLocationSavedEvent -> { - // Hide camera hover marker when custom location is picked from map. - displayToast("Specific location selected") - hoveringMarker?.visibility = View.GONE - isCameraMoved = false - } is FakeLocationFeature.SingleEvent.ErrorEvent -> { displayToast(event.error) - isCameraMoved = false - } - FakeLocationFeature.SingleEvent.RealLocationSelectedEvent -> { - displayToast("Real location selected") - hoveringMarker?.visibility = View.GONE - isCameraMoved = false } } } } + lifecycleScope.launchWhenStarted { viewModel.submitAction(Action.Init) } } override fun onAttach(context: Context) { @@ -206,25 +192,29 @@ class FakeLocationFragment : binding.mapView.addView(hoveringMarker) hoveringMarker?.visibility = View.GONE // Keep hovering marker hidden by default - mapboxMap.addOnCameraMoveStartedListener { - // Show marker when user starts to move across the map. - hoveringMarker?.visibility = if (binding.mapView.isEnabled) { - View.VISIBLE - } else { - View.GONE - } - isCameraMoved = true - } - - mapboxMap.addOnCameraMoveListener { - if (binding.mapView.isEnabled) { - viewModel.submitAction( - FakeLocationFeature.Action.UpdateLocationAction( - mapboxMap.cameraPosition.target - ) - ) - } - } + // mapboxMap.addOnCameraMoveStartedListener { + // // Show marker when user starts to move across the map. + // hoveringMarker?.visibility = if (binding.mapView.isEnabled) { + // View.VISIBLE + // } else { + // View.GONE + // } + // isCameraMoved = true + // } + // + // mapboxMap.addOnCameraMoveListener { + // if (binding.mapView.isEnabled) { + // mapboxMap.cameraPosition.target.let { + // viewModel.submitAction( + // Action.SetSpecificLocationAction( + // it.latitude.toFloat(), + // it.longitude.toFloat() + // ) + // ) + // } + // } + + // } // Bind click listeners once map is ready. bindClickListeners() } @@ -238,8 +228,8 @@ class FakeLocationFragment : delay(DEBOUNCE_PERIOD) ensureActive() try { - val value = editable.toString().toDouble() - val maxValue = if (isLat) 90.0 else 180.0 + val value = editable.toString().toFloat() + val maxValue = if (isLat) 90f else 180f if (value > maxValue || value < -maxValue) { throw NumberFormatException("value $value is out of bounds") @@ -251,12 +241,10 @@ class FakeLocationFragment : // Here, value is valid, try to send the values try { - val lat = binding.edittextLatitude.text.toString().toDouble() - val lon = binding.edittextLongitude.text.toString().toDouble() - if (lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) { - viewModel.submitAction( - FakeLocationFeature.Action.SetCustomFakeLocationAction(lat, lon) - ) + val lat = binding.edittextLatitude.text.toString().toFloat() + val lon = binding.edittextLongitude.text.toString().toFloat() + if (lat <= 90f && lat >= -90f && lon <= 180f && lon >= -180f) { + viewModel.submitAction(Action.SetSpecificLocationAction(lat, lon)) } } catch (e: NumberFormatException) {} } catch (e: NumberFormatException) { @@ -268,14 +256,16 @@ class FakeLocationFragment : } private fun bindClickListeners() { - binding.radioUseRealLocation.setOnClickListener { radioButton -> - toggleLocationType(radioButton) + binding.radioUseRealLocation.setOnClickListener { + viewModel.submitAction(Action.UseRealLocationAction) } - binding.radioUseRandomLocation.setOnClickListener { radioButton -> - toggleLocationType(radioButton) + binding.radioUseRandomLocation.setOnClickListener { + viewModel.submitAction(Action.UseRandomLocationAction) } - binding.radioUseSpecificLocation.setOnClickListener { radioButton -> - toggleLocationType(radioButton) + binding.radioUseSpecificLocation.setOnClickListener { + viewModel.submitAction( +Action.SetSpecificLocationAction(displayedLocation?.first?: 0f, displayedLocation?.second?: 0f) + ) } binding.edittextLatitude.addTextChangedListener( @@ -295,50 +285,25 @@ class FakeLocationFragment : ) } - private fun toggleLocationType(radioButton: View?) { - if (radioButton is RadioButton) { - val checked = radioButton.isChecked - when (radioButton.id) { - R.id.radio_use_real_location -> - if (checked) { - viewModel.submitAction( - FakeLocationFeature.Action.UseRealLocationAction - ) - } - R.id.radio_use_random_location -> - if (checked) { - viewModel.submitAction( - FakeLocationFeature.Action.UseRandomLocationAction( - resources.getStringArray(R.array.cities) - ) - ) - } - R.id.radio_use_specific_location -> - if (checked) { - viewModel.submitAction( - FakeLocationFeature.Action.UseSpecificLocationAction - ) - } - } - } - } - override fun render(state: FakeLocationFeature.State) { - binding.radioUseRandomLocation.isChecked = (state.location.mode == LocationMode.RANDOM_LOCATION) + hoveringMarker?.visibility = View.GONE + isCameraMoved = false + + binding.radioUseRandomLocation.isChecked = (state.mode == LocationMode.RANDOM_LOCATION) binding.radioUseSpecificLocation.isChecked = - (state.location.mode == LocationMode.CUSTOM_LOCATION) - binding.radioUseRealLocation.isChecked = (state.location.mode == LocationMode.REAL_LOCATION) + (state.mode == LocationMode.SPECIFIC_LOCATION) + binding.radioUseRealLocation.isChecked = (state.mode == LocationMode.REAL_LOCATION) - binding.mapView.isEnabled = (state.location.mode == LocationMode.CUSTOM_LOCATION) + binding.mapView.isEnabled = (state.mode == LocationMode.SPECIFIC_LOCATION) - binding.textlayoutLatitude.isVisible = (state.location.mode == LocationMode.CUSTOM_LOCATION) - binding.textlayoutLongitude.isVisible = (state.location.mode == LocationMode.CUSTOM_LOCATION) + binding.textlayoutLatitude.isVisible = (state.mode == LocationMode.SPECIFIC_LOCATION) + binding.textlayoutLongitude.isVisible = (state.mode == LocationMode.SPECIFIC_LOCATION) - binding.edittextLatitude.setText(state.location.latitude.toString()) - binding.edittextLongitude.setText(state.location.longitude.toString()) + binding.edittextLatitude.setText(state.specificLatitude?.toString()) + binding.edittextLongitude.setText(state.specificLongitude?.toString()) } - override fun actions(): Flow<FakeLocationFeature.Action> = viewModel.actions + override fun actions(): Flow<Action> = viewModel.actions @SuppressLint("MissingPermission") private fun enableLocationPlugin(@NonNull loadedMapStyle: Style) { diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt index b73c228..70ee0c1 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt @@ -20,17 +20,24 @@ package foundation.e.privacycentralapp.features.location import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import foundation.e.privacycentralapp.common.Factory +import foundation.e.privacycentralapp.domain.usecases.FakeLocationStateUseCase +import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch -class FakeLocationViewModel(private val locationApi: LocationApiDelegate) : ViewModel() { +class FakeLocationViewModel( + private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, + private val fakeLocationStateUseCase: FakeLocationStateUseCase) : ViewModel() { private val _actions = MutableSharedFlow<FakeLocationFeature.Action>() val actions = _actions.asSharedFlow() val fakeLocationFeature: FakeLocationFeature by lazy { - FakeLocationFeature.create(coroutineScope = viewModelScope, locationApi = locationApi) + FakeLocationFeature.create( + getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase, + fakeLocationStateUseCase = fakeLocationStateUseCase, + coroutineScope = viewModelScope) } fun submitAction(action: FakeLocationFeature.Action) { @@ -40,8 +47,10 @@ class FakeLocationViewModel(private val locationApi: LocationApiDelegate) : View } } -class FakeLocationViewModelFactory(private val locationApi: LocationApiDelegate) : Factory<FakeLocationViewModel> { +class FakeLocationViewModelFactory( + private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, + private val fakeLocationStateUseCase: FakeLocationStateUseCase) : Factory<FakeLocationViewModel> { override fun create(): FakeLocationViewModel { - return FakeLocationViewModel((locationApi)) + return FakeLocationViewModel(getQuickPrivacyStateUseCase, fakeLocationStateUseCase) } } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt deleted file mode 100644 index 88fef3e..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2021 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.location - -import android.app.AppOpsManager -import android.util.Log -import foundation.e.privacymodules.location.IFakeLocation -import foundation.e.privacymodules.permissions.PermissionsPrivacyModule -import foundation.e.privacymodules.permissions.data.AppOpModes -import foundation.e.privacymodules.permissions.data.ApplicationDescription - -class LocationApiDelegate( - private val fakeLocationModule: IFakeLocation, - private val permissionsModule: PermissionsPrivacyModule, - private val appDesc: ApplicationDescription -) { - - private val TAG = LocationApiDelegate::class.simpleName - - fun setFakeLocation(latitude: Double, longitude: Double) { - if (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) != AppOpModes.ALLOWED) { - permissionsModule.setAppOpMode( - appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, - AppOpModes.ALLOWED - ) - } - try { - fakeLocationModule.startFakeLocation() - } catch (e: Exception) { - Log.e(TAG, "Can't startFakeLocation", e) - } - fakeLocationModule.setFakeLocation(latitude, longitude) - } - - fun stopFakeLocation() { - try { - permissionsModule.setAppOpMode( - appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, - AppOpModes.IGNORED - ) - permissionsModule.setAppOpMode( - appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, - AppOpModes.IGNORED - ) - fakeLocationModule.stopFakeLocation() - } catch (e: Exception) { - Log.e(TAG, "Can't stop FakeLocation", e) - } - } - - fun startRealLocation() { - stopFakeLocation() - try { - permissionsModule.setAppOpMode( - appDesc, AppOpsManager.OPSTR_COARSE_LOCATION, - AppOpModes.ALLOWED - ) - permissionsModule.setAppOpMode( - appDesc, AppOpsManager.OPSTR_FINE_LOCATION, - AppOpModes.ALLOWED - ) - } catch (e: Exception) { - Log.e(TAG, "Can't start RealLocation", e) - } - } -} |
