Add doze disable preference for downloads

This commit is contained in:
Koitharu
2023-12-08 12:18:18 +02:00
parent ae16110a80
commit 66356dc094
7 changed files with 95 additions and 49 deletions

View File

@@ -574,6 +574,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_CF_CONTRAST = "cf_contrast"
const val KEY_CF_INVERTED = "cf_inverted"
const val KEY_CF_GRAYSCALE = "cf_grayscale"
const val KEY_IGNORE_DOZE = "ignore_dose"
// About
const val KEY_APP_UPDATE = "app_update"

View File

@@ -5,7 +5,9 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.work.WorkInfo
import coil.ImageLoader
import coil.request.SuccessResult
@@ -59,6 +61,7 @@ fun downloadItemAD(
val chaptersAdapter = BaseListAdapter<DownloadChapter>()
.addDelegate(ListItemType.CHAPTER, downloadChapterAD())
binding.recyclerViewChapters.addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL))
binding.recyclerViewChapters.adapter = chaptersAdapter
binding.buttonCancel.setOnClickListener(clickListener)
binding.buttonPause.setOnClickListener(clickListener)

View File

@@ -17,6 +17,7 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
import org.koitharu.kotatsu.local.data.LocalStorageManager
import org.koitharu.kotatsu.settings.storage.MangaDirectorySelectDialog
import org.koitharu.kotatsu.settings.storage.directories.MangaDirectoriesActivity
import org.koitharu.kotatsu.settings.utils.DozeHelper
import javax.inject.Inject
@AndroidEntryPoint
@@ -24,6 +25,8 @@ class DownloadsSettingsFragment :
BasePreferenceFragment(R.string.downloads),
SharedPreferences.OnSharedPreferenceChangeListener {
private val dozeHelper = DozeHelper(this)
@Inject
lateinit var storageManager: LocalStorageManager
@@ -32,6 +35,7 @@ class DownloadsSettingsFragment :
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_downloads)
dozeHelper.updatePreference()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -74,6 +78,10 @@ class DownloadsSettingsFragment :
true
}
AppSettings.KEY_IGNORE_DOZE -> {
dozeHelper.startIgnoreDoseActivity()
}
else -> super.onPreferenceTreeClick(preference)
}
}

View File

@@ -1,43 +1,36 @@
package org.koitharu.kotatsu.settings.tracker
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.PowerManager
import android.provider.Settings
import android.text.style.URLSpan
import android.view.View
import androidx.core.net.toUri
import androidx.core.text.buildSpannedString
import androidx.core.text.inSpans
import androidx.fragment.app.viewModels
import androidx.preference.MultiSelectListPreference
import androidx.preference.Preference
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.powerManager
import org.koitharu.kotatsu.settings.tracker.categories.TrackerCategoriesConfigSheet
import org.koitharu.kotatsu.settings.utils.DozeHelper
import org.koitharu.kotatsu.settings.utils.MultiSummaryProvider
import org.koitharu.kotatsu.tracker.work.TrackerNotificationChannels
import javax.inject.Inject
private const val KEY_IGNORE_DOZE = "ignore_dose"
@AndroidEntryPoint
class TrackerSettingsFragment :
BasePreferenceFragment(R.string.check_for_new_chapters),
SharedPreferences.OnSharedPreferenceChangeListener {
private val viewModel by viewModels<TrackerSettingsViewModel>()
private val dozeHelper = DozeHelper(this)
@Inject
lateinit var channels: TrackerNotificationChannels
@@ -57,13 +50,12 @@ class TrackerSettingsFragment :
}
}
}
updateDozePreference()
dozeHelper.updatePreference()
updateCategoriesEnabled()
}
override fun onResume() {
super.onResume()
updateDozePreference()
updateNotificationsSummary()
}
@@ -111,8 +103,8 @@ class TrackerSettingsFragment :
true
}
KEY_IGNORE_DOZE -> {
startIgnoreDoseActivity(preference.context)
AppSettings.KEY_IGNORE_DOZE -> {
dozeHelper.startIgnoreDoseActivity()
true
}
@@ -120,12 +112,6 @@ class TrackerSettingsFragment :
}
}
private fun updateDozePreference() {
findPreference<Preference>(KEY_IGNORE_DOZE)?.run {
isVisible = isDozeIgnoreAvailable(context)
}
}
private fun updateNotificationsSummary() {
val pref = findPreference<Preference>(AppSettings.KEY_NOTIFICATIONS_SETTINGS) ?: return
pref.setSummary(
@@ -148,34 +134,4 @@ class TrackerSettingsFragment :
getString(R.string.enabled_d_of_d, count[0], count[1])
}
}
@SuppressLint("BatteryLife")
private fun startIgnoreDoseActivity(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show()
return
}
val packageName = context.packageName
val powerManager = context.powerManager ?: return
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
try {
val intent = Intent(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
"package:$packageName".toUri(),
)
startActivity(intent)
} catch (e: ActivityNotFoundException) {
Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show()
}
}
}
private fun isDozeIgnoreAvailable(context: Context): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false
}
val packageName = context.packageName
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
return !powerManager.isIgnoringBatteryOptimizations(packageName)
}
}

View File

@@ -0,0 +1,69 @@
package org.koitharu.kotatsu.settings.utils
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.net.toUri
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.snackbar.Snackbar
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.powerManager
@SuppressLint("BatteryLife")
class DozeHelper(
private val fragment: PreferenceFragmentCompat,
) {
private val startForDozeResult = fragment.registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
) {
updatePreference()
}
fun updatePreference() {
val preference = fragment.findPreference<Preference>(AppSettings.KEY_IGNORE_DOZE) ?: return
preference.isVisible = isDozeIgnoreAvailable()
}
fun startIgnoreDoseActivity(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Snackbar.make(fragment.listView ?: return false, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show()
return false
}
val context = fragment.context ?: return false
val packageName = context.packageName
val powerManager = context.powerManager ?: return false
return if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
try {
val intent = Intent(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
"package:$packageName".toUri(),
)
startForDozeResult.launch(intent)
true
} catch (e: ActivityNotFoundException) {
Snackbar.make(fragment.listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show()
false
}
} else {
false
}
}
private fun isDozeIgnoreAvailable(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false
}
val context = fragment.context ?: return false
val packageName = context.packageName
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
return !powerManager.isIgnoringBatteryOptimizations(packageName)
}
}

View File

@@ -543,4 +543,5 @@
<string name="error_filter_locale_genre_not_supported">Filtering by both genres and locale is not supported by this source</string>
<string name="error_filter_states_genre_not_supported">Filtering by both genres and states is not supported by this source</string>
<string name="genres_search_hint">Start typing the genre name</string>
<string name="disable_battery_optimization_summary_downloads">Might help with getting the download started if you have any issues with it</string>
</resources>

View File

@@ -19,6 +19,14 @@
android:summary="@string/downloads_wifi_only_summary"
android:title="@string/downloads_wifi_only" />
<Preference
android:key="ignore_dose"
android:persistent="false"
android:summary="@string/disable_battery_optimization_summary_downloads"
android:title="@string/disable_battery_optimization"
app:allowDividerAbove="true"
app:isPreferenceVisible="false" />
<Preference
android:icon="@drawable/ic_info_outline"
android:key="tracker_notifications_info"