diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
index 12392313e273..2c9efd17ed97 100644
--- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
@@ -112,6 +112,7 @@ import com.ichi2.libanki.utils.TimeManager
import com.ichi2.themes.StyledProgressDialog
import com.ichi2.ui.BadgeDrawableBuilder
import com.ichi2.utils.*
+import com.ichi2.utils.NetworkUtils.isActiveNetworkMetered
import com.ichi2.utils.Permissions.hasStorageAccessPermission
import com.ichi2.widget.WidgetStatus
import kotlinx.coroutines.Job
@@ -923,14 +924,15 @@ open class DeckPicker :
private fun automaticSync() {
val preferences = AnkiDroidApp.getSharedPrefs(baseContext)
- // Check whether the option is selected, the user is signed in and last sync was AUTOMATIC_SYNC_TIME ago
- // (currently 10 minutes)
+ // Check whether the option is selected, the user is signed in, last sync was AUTOMATIC_SYNC_TIME ago
+ // (currently 10 minutes), and is not under a metered connection (if not allowed by preference)
val isLoggedIn = preferences.getString("hkey", "")!!.isNotEmpty()
val lastSyncTime = preferences.getLong("lastSyncTime", 0)
val autoSyncIsEnabled = preferences.getBoolean("automaticSyncMode", false)
val syncIntervalPassed = TimeManager.time.intTimeMS() - lastSyncTime > AUTOMATIC_SYNC_MIN_INTERVAL
+ val isNotBlockedByMeteredConnection = preferences.getBoolean(getString(R.string.metered_sync_key), false) || !isActiveNetworkMetered()
- if (isLoggedIn && autoSyncIsEnabled && Connection.isOnline && syncIntervalPassed) {
+ if (isLoggedIn && autoSyncIsEnabled && Connection.isOnline && syncIntervalPassed && isNotBlockedByMeteredConnection) {
Timber.i("Triggering Automatic Sync")
sync()
}
@@ -1563,25 +1565,30 @@ open class DeckPicker :
Timber.w("User not logged in")
mPullToSyncWrapper.isRefreshing = false
showSyncErrorDialog(SyncErrorDialog.DIALOG_USER_NOT_LOGGED_IN_SYNC)
- } else {
+ return
+ }
+ /** Nested function that makes the connection to
+ * the sync server and starts syncing the data */
+ fun doSync() {
val syncMedia = preferences.getBoolean("syncFetchesMedia", true)
-
if (!BackendFactory.defaultLegacySchema) {
handleNewSync(conflict, syncMedia)
} else {
- Connection.sync(
- mSyncListener,
- Connection.Payload(
- arrayOf(
- hkey,
- syncMedia,
- conflict,
- HostNumFactory.getInstance(baseContext)
- )
- )
- )
+ val data = arrayOf(hkey, syncMedia, conflict, HostNumFactory.getInstance(baseContext))
+ Connection.sync(mSyncListener, Connection.Payload(data))
}
}
+ // Warn the user in case the connection is metered
+ val meteredSyncIsAllowed = preferences.getBoolean(getString(R.string.metered_sync_key), false)
+ if (!meteredSyncIsAllowed && isActiveNetworkMetered()) {
+ MaterialDialog(this).show {
+ message(R.string.metered_sync_warning)
+ positiveButton(R.string.dialog_continue) { doSync() }
+ negativeButton(R.string.dialog_cancel)
+ }
+ } else {
+ doSync()
+ }
}
private val mSyncListener: Connection.TaskListener = object : CancellableTaskListener {
diff --git a/AnkiDroid/src/main/res/values/03-dialogs.xml b/AnkiDroid/src/main/res/values/03-dialogs.xml
index 6cd676b091f8..b6020e3aebc3 100644
--- a/AnkiDroid/src/main/res/values/03-dialogs.xml
+++ b/AnkiDroid/src/main/res/values/03-dialogs.xml
@@ -257,6 +257,7 @@
- An automatic sync may be triggered in %d second
- An automatic sync may be triggered in %d seconds
+ Your connection is metered. Data transfer may cost money
Number of new cards to see today in this deck.
Number of cards due today in this deck.
Number of cards in learning in this deck.
Fetch media on sync
Automatically fetch missing media when syncing
AnkiWeb account
@@ -109,6 +110,8 @@
minutes ago.
Display synchronization status
Change the sync icon when changes can be uploaded
+ Allow sync on metered connections
+ If disabled, you will be warned if you try to sync on a metered connection
Theme
Day theme
Night theme
diff --git a/AnkiDroid/src/main/res/values/preferences.xml b/AnkiDroid/src/main/res/values/preferences.xml
index 7c3595841e2c..96eb93b49fef 100644
--- a/AnkiDroid/src/main/res/values/preferences.xml
+++ b/AnkiDroid/src/main/res/values/preferences.xml
@@ -27,6 +27,7 @@
automaticSyncMode
force_full_sync
showSyncStatusBadge
+ allowMetered
custom_sync_server_link
appearance_preference_group
diff --git a/AnkiDroid/src/main/res/xml/preferences_sync.xml b/AnkiDroid/src/main/res/xml/preferences_sync.xml
index 4bf7f57b07c7..5d04382c8b38 100644
--- a/AnkiDroid/src/main/res/xml/preferences_sync.xml
+++ b/AnkiDroid/src/main/res/xml/preferences_sync.xml
@@ -42,6 +42,11 @@
android:key="@string/sync_status_badge_key"
android:summary="@string/sync_status_badge_summ"
android:title="@string/sync_status_badge" />
+