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="support_email">support@tasks.org</string>
<string name="default_reverse_geocoder">1</string> <!-- Nominatim --> <string name="default_reverse_geocoder">1</string> <!-- Nominatim -->
<string name="default_maps">1</string> <!-- OpenStreetMaps --> <string name="default_maps">1</string> <!-- OpenStreetMaps -->
<string name="default_geofence_service">1</string> <!-- Android LocationManager -->
</resources> </resources>

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

@ -13,6 +13,8 @@ class GeofenceApi @Inject constructor(
) { ) {
suspend fun registerAll() = locationDao.getPlacesWithGeofences().forEach { update(it) } 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(taskId: Long) = update(locationDao.getPlaceForTask(taskId))
suspend fun update(place: String) = update(locationDao.getPlace(place)) suspend fun update(place: String) = update(locationDao.getPlace(place))
@ -26,9 +28,11 @@ class GeofenceApi @Inject constructor(
Timber.d("Adding geofence for %s", it) Timber.d("Adding geofence for %s", it)
client.addGeofences(it) client.addGeofences(it)
} }
?: place.let { ?: cancel(place)
Timber.d("Removing geofence for %s", it) }
client.removeGeofences(it)
} 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 package org.tasks.location
import android.app.Activity.RESULT_CANCELED
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.app.Dialog import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -52,9 +54,7 @@ class LocationPermissionDialog : DialogFragment() {
return dialogBuilder.newDialog(R.string.missing_permissions) return dialogBuilder.newDialog(R.string.missing_permissions)
.setView(binding.root) .setView(binding.root)
.setNegativeButton(R.string.cancel) { _, _ -> .setNegativeButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
dismiss()
}
.setNeutralButton(R.string.TLA_menu_settings) { _, _ -> .setNeutralButton(R.string.TLA_menu_settings) { _, _ ->
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
addCategory(Intent.CATEGORY_DEFAULT) addCategory(Intent.CATEGORY_DEFAULT)
@ -88,6 +88,10 @@ class LocationPermissionDialog : DialogFragment() {
} }
} }
override fun onCancel(dialog: DialogInterface) {
targetFragment?.onActivityResult(targetRequestCode, RESULT_CANCELED, null)
}
companion object { companion object {
fun newLocationPermissionDialog( fun newLocationPermissionDialog(
targetFragment: Fragment, targetFragment: Fragment,

@ -1,13 +1,23 @@
package org.tasks.preferences.fragments package org.tasks.preferences.fragments
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.SwitchPreference
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R import org.tasks.R
import org.tasks.Tasks.Companion.IS_GOOGLE_PLAY import org.tasks.Tasks.Companion.IS_GOOGLE_PLAY
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.gtasks.PlayServices import org.tasks.gtasks.PlayServices
import org.tasks.injection.InjectingPreferenceFragment 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 org.tasks.ui.Toaster
import javax.inject.Inject import javax.inject.Inject
@ -17,6 +27,9 @@ class LocationPreferences : InjectingPreferenceFragment() {
@Inject lateinit var playServices: PlayServices @Inject lateinit var playServices: PlayServices
@Inject lateinit var inventory: Inventory @Inject lateinit var inventory: Inventory
@Inject lateinit var toaster: Toaster @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 override fun getPreferenceXml() = R.xml.preferences_location
@ -24,14 +37,40 @@ class LocationPreferences : InjectingPreferenceFragment() {
if (IS_GOOGLE_PLAY) { if (IS_GOOGLE_PLAY) {
findPreference(R.string.p_place_provider) findPreference(R.string.p_place_provider)
.setOnPreferenceChangeListener(this::onPlaceSearchChanged) .setOnPreferenceChangeListener(this::onPlaceSearchChanged)
findPreference(R.string.p_geofence_service)
.setOnPreferenceChangeListener(this::onGeofenceServiceChanged)
} else { } else {
disable( disable(
R.string.p_map_tiles, R.string.p_map_tiles,
R.string.p_place_provider, 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 = private fun onPlaceSearchChanged(preference: Preference, newValue: Any): Boolean =
if (newValue.toString().toIntOrNull() ?: 0 == 1) { if (newValue.toString().toIntOrNull() ?: 0 == 1) {
if (!playServices.refreshAndCheck()) { if (!playServices.refreshAndCheck()) {
@ -46,4 +85,37 @@ class LocationPreferences : InjectingPreferenceFragment() {
} else { } else {
true 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>0</item>
<item>1</item> <item>1</item>
</string-array> </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> </resources>

@ -403,6 +403,8 @@
<string name="openstreetmap">OpenStreetMap</string> <string name="openstreetmap">OpenStreetMap</string>
<string name="android">Android</string> <string name="android">Android</string>
<string name="p_place_provider">place_provider_v2</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="preference_screen">preference_screen</string>
<string name="p_add_to_top">google_tasks_add_to_top</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> <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="maps">Maps</string>
<string name="map_tiles">Map tiles</string> <string name="map_tiles">Map tiles</string>
<string name="map_theme_use_app_theme">Use app theme</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> </resources>

@ -2,6 +2,24 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="@string/preference_screen"> 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 <PreferenceCategory
android:key="@string/maps" android:key="@string/maps"
android:title="@string/maps"> android:title="@string/maps">

Loading…
Cancel
Save