Add geofence service preference

pull/1375/head
Alex Baker 5 years ago
parent 9f2401e927
commit 76af1aeaba

@ -8,4 +8,5 @@
<string name="support_email">support@tasks.org</string>
<string name="default_reverse_geocoder">1</string> <!-- Nominatim -->
<string name="default_maps">1</string> <!-- OpenStreetMaps -->
<string name="default_geofence_service">1</string> <!-- Android LocationManager -->
</resources>

@ -8,4 +8,5 @@
<string name="support_email">play-support@tasks.org</string>
<string name="default_reverse_geocoder">0</string> <!-- Mapbox -->
<string name="default_maps">0</string> <!-- Google Maps -->
<string name="default_geofence_service">0</string> <!-- Google Play Location Services -->
</resources>

@ -13,6 +13,8 @@ class GeofenceApi @Inject constructor(
) {
suspend fun registerAll() = locationDao.getPlacesWithGeofences().forEach { update(it) }
suspend fun cancelAll() = locationDao.getPlacesWithGeofences().forEach { cancel(it) }
suspend fun update(taskId: Long) = update(locationDao.getPlaceForTask(taskId))
suspend fun update(place: String) = update(locationDao.getPlace(place))
@ -26,9 +28,11 @@ class GeofenceApi @Inject constructor(
Timber.d("Adding geofence for %s", it)
client.addGeofences(it)
}
?: place.let {
Timber.d("Removing geofence for %s", it)
client.removeGeofences(it)
?: cancel(place)
}
private fun cancel(place: Place?) = place?.let {
Timber.d("Removing geofence for %s", place)
client.removeGeofences(place)
}
}

@ -1,7 +1,9 @@
package org.tasks.location
import android.app.Activity.RESULT_CANCELED
import android.app.Activity.RESULT_OK
import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@ -52,9 +54,7 @@ class LocationPermissionDialog : DialogFragment() {
return dialogBuilder.newDialog(R.string.missing_permissions)
.setView(binding.root)
.setNegativeButton(R.string.cancel) { _, _ ->
dismiss()
}
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
.setNeutralButton(R.string.TLA_menu_settings) { _, _ ->
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
addCategory(Intent.CATEGORY_DEFAULT)
@ -88,6 +88,10 @@ class LocationPermissionDialog : DialogFragment() {
}
}
override fun onCancel(dialog: DialogInterface) {
targetFragment?.onActivityResult(targetRequestCode, RESULT_CANCELED, null)
}
companion object {
fun newLocationPermissionDialog(
targetFragment: Fragment,

@ -1,13 +1,23 @@
package org.tasks.preferences.fragments
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.SwitchPreference
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.Tasks.Companion.IS_GOOGLE_PLAY
import org.tasks.billing.Inventory
import org.tasks.gtasks.PlayServices
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.location.GeofenceApi
import org.tasks.location.LocationPermissionDialog.Companion.newLocationPermissionDialog
import org.tasks.preferences.PermissionChecker
import org.tasks.preferences.Preferences
import org.tasks.ui.Toaster
import javax.inject.Inject
@ -17,6 +27,9 @@ class LocationPreferences : InjectingPreferenceFragment() {
@Inject lateinit var playServices: PlayServices
@Inject lateinit var inventory: Inventory
@Inject lateinit var toaster: Toaster
@Inject lateinit var geofenceApi: GeofenceApi
@Inject lateinit var permissionChecker: PermissionChecker
@Inject lateinit var preferences: Preferences
override fun getPreferenceXml() = R.xml.preferences_location
@ -24,14 +37,40 @@ class LocationPreferences : InjectingPreferenceFragment() {
if (IS_GOOGLE_PLAY) {
findPreference(R.string.p_place_provider)
.setOnPreferenceChangeListener(this::onPlaceSearchChanged)
findPreference(R.string.p_geofence_service)
.setOnPreferenceChangeListener(this::onGeofenceServiceChanged)
} else {
disable(
R.string.p_map_tiles,
R.string.p_place_provider,
R.string.p_geofence_service
)
}
}
override fun onResume() {
super.onResume()
updatePermissions()
}
private fun updatePermissions() {
val hasPermissions = permissionChecker.canAccessBackgroundLocation()
preferences.setBoolean(R.string.p_location_based_reminders, hasPermissions)
with((findPreference(R.string.p_location_based_reminders) as SwitchPreference)) {
isChecked = hasPermissions
isEnabled = !hasPermissions
setOnPreferenceClickListener {
if (!permissionChecker.canAccessBackgroundLocation()) {
newLocationPermissionDialog(this@LocationPreferences, REQUEST_BACKGROUND_LOCATION)
.show(parentFragmentManager, FRAG_TAG_LOCATION_PERMISSION)
}
false
}
}
findPreference(R.string.p_geofence_service).isEnabled = hasPermissions && IS_GOOGLE_PLAY
}
private fun onPlaceSearchChanged(preference: Preference, newValue: Any): Boolean =
if (newValue.toString().toIntOrNull() ?: 0 == 1) {
if (!playServices.refreshAndCheck()) {
@ -46,4 +85,37 @@ class LocationPreferences : InjectingPreferenceFragment() {
} else {
true
}
private fun onGeofenceServiceChanged(preference: Preference, newValue: Any): Boolean =
if (newValue.toString().toIntOrNull() ?: 0 == 1) {
if (!playServices.refreshAndCheck()) {
playServices.resolve(activity)
false
} else {
geofenceChanged()
}
} else {
geofenceChanged()
}
private fun geofenceChanged(): Boolean {
lifecycleScope.launch {
withContext(NonCancellable) {
geofenceApi.cancelAll()
}
showRestartDialog()
}
return true
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) =
when (requestCode) {
REQUEST_BACKGROUND_LOCATION -> updatePermissions()
else -> super.onActivityResult(requestCode, resultCode, data)
}
companion object {
private const val FRAG_TAG_LOCATION_PERMISSION = "frag_tag_location_permissions"
private const val REQUEST_BACKGROUND_LOCATION = 10101
}
}

@ -301,4 +301,14 @@
<item>0</item>
<item>1</item>
</string-array>
<string-array name="geofence_service_names">
<item>@string/google_play_location_service</item>
<item>@string/android_location_services</item>
</string-array>
<string-array name="geofence_service_values">
<item>0</item>
<item>1</item>
</string-array>
</resources>

@ -403,6 +403,8 @@
<string name="openstreetmap">OpenStreetMap</string>
<string name="android">Android</string>
<string name="p_place_provider">place_provider_v2</string>
<string name="p_location_based_reminders">location_based_reminders</string>
<string name="p_geofence_service">geofence_service</string>
<string name="preference_screen">preference_screen</string>
<string name="p_add_to_top">google_tasks_add_to_top</string>
<string name="p_google_tasks_position_hack">google_tasks_position_hack</string>

@ -703,4 +703,8 @@ File %1$s contained %2$s.\n\n
<string name="maps">Maps</string>
<string name="map_tiles">Map tiles</string>
<string name="map_theme_use_app_theme">Use app theme</string>
<string name="location_based_reminders">Location-based reminders</string>
<string name="geofence_service">Geofence service</string>
<string name="google_play_location_service">Google Play location service</string>
<string name="android_location_services">Android location service</string>
</resources>

@ -2,6 +2,24 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="@string/preference_screen">
<PreferenceCategory
android:title="@string/location_based_reminders">
<SwitchPreference
android:defaultValue="false"
android:key="@string/p_location_based_reminders"
android:title="@string/enabled" />
<ListPreference
android:defaultValue="@string/default_geofence_service"
android:key="@string/p_geofence_service"
android:title="@string/geofence_service"
android:entries="@array/geofence_service_names"
android:entryValues="@array/geofence_service_values"
android:summary="%s" />
</PreferenceCategory>
<PreferenceCategory
android:key="@string/maps"
android:title="@string/maps">

Loading…
Cancel
Save