From dc9f661066eb8377957939b11fc7ea6d9c4113d7 Mon Sep 17 00:00:00 2001 From: liveHarshit Date: Wed, 26 Jun 2019 17:46:36 +0530 Subject: [PATCH] feat: Implement location feature in f-droid (#2006) --- .../search/location/GeoLocationViewModel.kt | 24 +++++--- .../search/location/LocationServiceImpl.kt | 50 +++++++++++++++- .../general/welcome/WelcomeFragment.kt | 39 ------------- app/src/main/AndroidManifest.xml | 2 + .../openevent/general/OpenEventGeneral.kt | 4 +- .../search/location/SearchLocationFragment.kt | 11 ++-- .../general/welcome/WelcomeFragment.kt | 39 +++++-------- app/src/playStore/AndroidManifest.xml | 6 -- .../general/di/FlavorSpecificModules.kt | 9 --- .../general/welcome/WelcomeViewModel.kt | 58 ------------------- 10 files changed, 91 insertions(+), 151 deletions(-) delete mode 100644 app/src/fdroid/java/org/fossasia/openevent/general/welcome/WelcomeFragment.kt rename app/src/{playStore => main}/java/org/fossasia/openevent/general/welcome/WelcomeFragment.kt (76%) delete mode 100644 app/src/playStore/AndroidManifest.xml delete mode 100644 app/src/playStore/java/org/fossasia/openevent/general/di/FlavorSpecificModules.kt delete mode 100644 app/src/playStore/java/org/fossasia/openevent/general/welcome/WelcomeViewModel.kt diff --git a/app/src/fdroid/java/org/fossasia/openevent/general/search/location/GeoLocationViewModel.kt b/app/src/fdroid/java/org/fossasia/openevent/general/search/location/GeoLocationViewModel.kt index 507355bbde..199ac3a231 100644 --- a/app/src/fdroid/java/org/fossasia/openevent/general/search/location/GeoLocationViewModel.kt +++ b/app/src/fdroid/java/org/fossasia/openevent/general/search/location/GeoLocationViewModel.kt @@ -3,20 +3,30 @@ package org.fossasia.openevent.general.search.location import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.rxkotlin.plusAssign import org.fossasia.openevent.general.common.SingleLiveEvent +import java.lang.IllegalArgumentException -class GeoLocationViewModel(locationService: LocationService) : ViewModel() { +class GeoLocationViewModel(private val locationService: LocationService) : ViewModel() { private val mutableLocation = MutableLiveData() val location: LiveData = mutableLocation - private val mutableVisibility = MutableLiveData(false) - val currentLocationVisibility: LiveData = mutableVisibility - private val mutableOpenLocationSettings = MutableLiveData() - val openLocationSettings: LiveData = mutableOpenLocationSettings private val mutableErrorMessage = SingleLiveEvent() val errorMessage: LiveData = mutableErrorMessage + private val compositeDisposable = CompositeDisposable() fun configure() { - mutableVisibility.value = false - return + compositeDisposable += locationService.getAdministrativeArea() + .subscribe({ + mutableLocation.value = it + }, { + mutableErrorMessage.value = if (it is IllegalArgumentException) "No area found" + else "Something went wrong" + }) + } + + override fun onCleared() { + super.onCleared() + compositeDisposable.clear() } } diff --git a/app/src/fdroid/java/org/fossasia/openevent/general/search/location/LocationServiceImpl.kt b/app/src/fdroid/java/org/fossasia/openevent/general/search/location/LocationServiceImpl.kt index 181a7f3604..05914e8d17 100644 --- a/app/src/fdroid/java/org/fossasia/openevent/general/search/location/LocationServiceImpl.kt +++ b/app/src/fdroid/java/org/fossasia/openevent/general/search/location/LocationServiceImpl.kt @@ -1,11 +1,57 @@ package org.fossasia.openevent.general.search.location +import android.annotation.SuppressLint import android.content.Context +import android.location.Geocoder +import android.location.Location +import android.location.LocationListener +import android.location.LocationManager +import android.os.Bundle import io.reactivex.Single +import java.lang.IllegalArgumentException +import java.util.Locale -class LocationServiceImpl(context: Context) : LocationService { +class LocationServiceImpl(private val context: Context) : LocationService { + @SuppressLint("MissingPermission") override fun getAdministrativeArea(): Single { - throw IllegalStateException("Attempt to use location functionality in F-Droid flavor") + val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as? LocationManager + ?: return Single.error(IllegalStateException()) + val geoCoder = Geocoder(context, Locale.getDefault()) + + return Single.create { emitter -> + try { + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, + object : LocationListener { + override fun onLocationChanged(location: Location?) { + if (location == null) { + emitter.onError(java.lang.IllegalStateException()) + return + } + val addresses = geoCoder.getFromLocation(location.latitude, location.longitude, 1) + try { + val adminArea = addresses[0].adminArea + emitter.onSuccess(adminArea) + } catch (e: IllegalArgumentException) { + emitter.onError(e) + } + } + + override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) { + // To change body of created functions use File | Settings | File Templates. + } + + override fun onProviderEnabled(provider: String?) { + // To change body of created functions use File | Settings | File Templates. + } + + override fun onProviderDisabled(provider: String?) { + // To change body of created functions use File | Settings | File Templates. + } + }) + } catch (e: SecurityException) { + emitter.onError(e) + } + } } } diff --git a/app/src/fdroid/java/org/fossasia/openevent/general/welcome/WelcomeFragment.kt b/app/src/fdroid/java/org/fossasia/openevent/general/welcome/WelcomeFragment.kt deleted file mode 100644 index aeb366b688..0000000000 --- a/app/src/fdroid/java/org/fossasia/openevent/general/welcome/WelcomeFragment.kt +++ /dev/null @@ -1,39 +0,0 @@ -package org.fossasia.openevent.general.welcome - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import kotlinx.android.synthetic.main.fragment_welcome.view.currentLocation -import kotlinx.android.synthetic.main.fragment_welcome.view.pickCityButton -import kotlinx.android.synthetic.main.fragment_welcome.view.skip -import org.fossasia.openevent.general.R - -const val WELCOME_FRAGMENT = "welcomeFragment" - -class WelcomeFragment : Fragment() { - private lateinit var rootView: View - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - rootView = inflater.inflate(R.layout.fragment_welcome, container, false) - - (activity as? AppCompatActivity)?.supportActionBar?.hide() - - rootView.currentLocation.visibility = View.GONE - - rootView.pickCityButton.setOnClickListener { - findNavController().navigate(WelcomeFragmentDirections.actionWelcomeToSearch()) - } - - rootView.skip.setOnClickListener { - findNavController().navigate(WelcomeFragmentDirections.actionWelcomeToAuth( - redirectedFrom = WELCOME_FRAGMENT - )) - } - - return rootView - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d987ed01fb..ebbcac4448 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,8 @@ + + () + private val geoLocationViewModel by viewModel() + val preference = Preference() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { rootView = inflater.inflate(R.layout.fragment_welcome, container, false) @@ -39,35 +42,25 @@ class WelcomeFragment : Fragment() { Navigation.findNavController(rootView).navigate(R.id.searchLocationFragment, null, Utils.getAnimSlide()) } - welcomeViewModel.currentLocationVisibility.observe(this, Observer { - rootView.currentLocation.visibility = View.GONE - }) - rootView.currentLocation.setOnClickListener { checkLocationPermission() - welcomeViewModel.configure() - rootView.locationProgressBar.visibility = View.VISIBLE + if (isLocationEnabled(requireContext())) { + geoLocationViewModel.configure() + rootView.locationProgressBar.visibility = View.VISIBLE + } } rootView.skip.setOnClickListener { redirectToAuth() } - welcomeViewModel.redirectToMain.observe(this, Observer { redirect -> - if (redirect) { - redirectToAuth() - } - }) - - welcomeViewModel.openLocationSettings.observe(this, Observer { open -> - if (open) { - val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) - startActivity(intent) - } + geoLocationViewModel.location.observe(this, Observer { + preference.putString(SAVED_LOCATION, it) + redirectToAuth() }) - welcomeViewModel.errorMessage.observe(this, Observer { message -> - rootView.locationProgressBar.visibility = View.VISIBLE + geoLocationViewModel.errorMessage.observe(this, Observer { message -> + rootView.locationProgressBar.visibility = View.GONE Snackbar.make(rootView, message, Snackbar.LENGTH_SHORT).show() }) @@ -78,7 +71,7 @@ class WelcomeFragment : Fragment() { when (requestCode) { LOCATION_PERMISSION_REQUEST -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - welcomeViewModel.configure() + geoLocationViewModel.configure() } else { Snackbar.make(rootView, "Cannot fetch location!", Snackbar.LENGTH_SHORT).show() rootView.locationProgressBar.visibility = View.GONE diff --git a/app/src/playStore/AndroidManifest.xml b/app/src/playStore/AndroidManifest.xml deleted file mode 100644 index 54ad734fbd..0000000000 --- a/app/src/playStore/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/app/src/playStore/java/org/fossasia/openevent/general/di/FlavorSpecificModules.kt b/app/src/playStore/java/org/fossasia/openevent/general/di/FlavorSpecificModules.kt deleted file mode 100644 index c26a90790b..0000000000 --- a/app/src/playStore/java/org/fossasia/openevent/general/di/FlavorSpecificModules.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.fossasia.openevent.general.di - -import org.fossasia.openevent.general.welcome.WelcomeViewModel -import org.koin.androidx.viewmodel.dsl.viewModel -import org.koin.dsl.module - -val flavorSpecificModule = module { - viewModel { WelcomeViewModel(get(), get()) } -} diff --git a/app/src/playStore/java/org/fossasia/openevent/general/welcome/WelcomeViewModel.kt b/app/src/playStore/java/org/fossasia/openevent/general/welcome/WelcomeViewModel.kt deleted file mode 100644 index a7dc538216..0000000000 --- a/app/src/playStore/java/org/fossasia/openevent/general/welcome/WelcomeViewModel.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.fossasia.openevent.general.welcome - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import io.reactivex.rxkotlin.plusAssign -import io.reactivex.disposables.CompositeDisposable -import org.fossasia.openevent.general.common.SingleLiveEvent -import org.fossasia.openevent.general.data.Preference -import org.fossasia.openevent.general.location.LocationPermissionException -import org.fossasia.openevent.general.location.NoLocationSourceException -import org.fossasia.openevent.general.search.location.LocationService - -const val SAVED_LOCATION = "LOCATION" - -class WelcomeViewModel(private val locationService: LocationService, private val preference: Preference) : ViewModel() { - - private val mutableRedirectToMain = MutableLiveData() - val redirectToMain: LiveData = mutableRedirectToMain - private val mutableVisibility = MutableLiveData() - val currentLocationVisibility: LiveData = mutableVisibility - private val mutableOpenLocationSettings = MutableLiveData() - val openLocationSettings: LiveData = mutableOpenLocationSettings - private val mutableErrorMessage = SingleLiveEvent() - val errorMessage: LiveData = mutableErrorMessage - - private val compositeDisposable = CompositeDisposable() - - fun configure() { - compositeDisposable += locationService.getAdministrativeArea() - .subscribe( - { adminArea -> - preference.putString(SAVED_LOCATION, adminArea) - mutableRedirectToMain.value = true - }, - { error -> - when (error) { - is NoLocationSourceException -> { - mutableErrorMessage.value = "No location sources are enabled" - mutableOpenLocationSettings.value = true - } - is LocationPermissionException -> { - mutableErrorMessage.value = "Please give the location permission" - } - else -> { - mutableErrorMessage.value = "Something went wrong" - mutableVisibility.value = false - } - } - } - ) - } - - override fun onCleared() { - super.onCleared() - compositeDisposable.clear() - } -}