[优化] 优化听书相关代码
This commit is contained in:
1 parent
65acfd9f51
commit
a5a88fb7b2
12 files changed
+123
-87
No files matched your search
@@ -69,6 +69,7 @@ object PreferKey {
|
|||||||
const val webDavAccount = "web_dav_account"
|
const val webDavAccount = "web_dav_account"
|
||||||
const val webDavPassword = "web_dav_password"
|
const val webDavPassword = "web_dav_password"
|
||||||
const val webDavDir = "webDavDir"
|
const val webDavDir = "webDavDir"
|
||||||
|
const val webServiceAutoStart = "webServiceAutoStart"
|
||||||
const val enableCustomExport = "enableCustomExport"
|
const val enableCustomExport = "enableCustomExport"
|
||||||
const val exportToWebDav = "webDavCacheBackup"
|
const val exportToWebDav = "webDavCacheBackup"
|
||||||
const val exportNoChapterName = "exportNoChapterName"
|
const val exportNoChapterName = "exportNoChapterName"
|
||||||
@@ -243,4 +244,6 @@ object PreferKey {
|
|||||||
|
|
||||||
const val showTip = "showTip"
|
const val showTip = "showTip"
|
||||||
const val sliderVibrator = "sliderVibrator"
|
const val sliderVibrator = "sliderVibrator"
|
||||||
|
const val audioCacheCleanTime = "audioCacheCleanTime"
|
||||||
|
const val audioPreDownloadNum = "audioPreDownloadNum"
|
||||||
}
|
}
|
||||||
@@ -20,9 +20,6 @@ import io.legado.app.utils.removePref
|
|||||||
import io.legado.app.utils.sysConfiguration
|
import io.legado.app.utils.sysConfiguration
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
// 【新增引用】为了支持文件清理操作
|
|
||||||
import java.io.File
|
|
||||||
import io.legado.app.utils.FileUtils
|
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate", "ConstPropertyName")
|
@Suppress("MemberVisibilityCanBePrivate", "ConstPropertyName")
|
||||||
object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
@@ -60,7 +57,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
var optimizeRender = CanvasRecorderFactory.isSupport
|
var optimizeRender = CanvasRecorderFactory.isSupport
|
||||||
&& appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
&& appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
||||||
var recordLog = appCtx.getPrefBoolean(PreferKey.recordLog)
|
var recordLog = appCtx.getPrefBoolean(PreferKey.recordLog)
|
||||||
|
var webServiceAutoStart = appCtx.getPrefBoolean(PreferKey.webServiceAutoStart)
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
when (key) {
|
when (key) {
|
||||||
|
|
||||||
@@ -976,39 +973,16 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
appCtx.putPrefBoolean(PreferKey.sliderVibrator, value)
|
appCtx.putPrefBoolean(PreferKey.sliderVibrator, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= 自定义功能区域 Start =================
|
|
||||||
|
|
||||||
// 1. 听书预加载数量
|
|
||||||
// 逻辑:从设置里读取字符串,转成数字。如果读不到,默认返回 10。
|
|
||||||
val audioPreDownloadNum: Int
|
val audioPreDownloadNum: Int
|
||||||
get() {
|
get() = appCtx.getPrefInt(PreferKey.audioPreDownloadNum, 10)
|
||||||
// 注意:EditTextPreference 保存的是 String
|
|
||||||
val str = appCtx.getPrefString("audioPreDownloadNum")
|
val audioCacheCleanTimeOrgin: Int
|
||||||
return str?.toIntOrNull() ?: 10
|
get() = appCtx.getPrefInt(PreferKey.audioCacheCleanTime, 10)
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 音频缓存保留时间 (返回毫秒)
|
|
||||||
// 逻辑:用户输入的是“分钟”,我们在这里把它乘以 60000 变成“毫秒”。
|
|
||||||
val audioCacheCleanTime: Long
|
val audioCacheCleanTime: Long
|
||||||
get() {
|
get() {
|
||||||
val str = appCtx.getPrefString("audioCacheCleanTime")
|
val str = appCtx.getPrefInt(PreferKey.audioCacheCleanTime, 10)
|
||||||
val minutes = str?.toLongOrNull() ?: 10L // 默认 10 分钟
|
return str * 60 * 1000L
|
||||||
return minutes * 60 * 1000L
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 【新增】手动清理 TTS 缓存
|
|
||||||
* 这个方法会自动寻找 externalCacheDir(外部存储),如果找不到再找内部。
|
|
||||||
* 确保和 Service 里的逻辑保持一致。
|
|
||||||
*/
|
|
||||||
fun clearTtsCache() {
|
|
||||||
val baseDir = appCtx.externalCacheDir ?: appCtx.cacheDir
|
|
||||||
// 清理音频文件
|
|
||||||
FileUtils.delete(baseDir.absolutePath + File.separator + "httpTTS")
|
|
||||||
// 清理数据库索引 (可选,建议一起清,防止索引还在但文件没了)
|
|
||||||
FileUtils.delete(baseDir.absolutePath + File.separator + "httpTTS_cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================= 自定义功能区域 End =================
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -65,11 +65,9 @@ import java.io.File
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.ConnectException
|
import java.net.ConnectException
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
import kotlin.coroutines.coroutineContext
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线朗读
|
* 在线朗读
|
||||||
* (完美匹配版:修复文件名MD5不一致 + 修复缓存不可见 + 修复0分钟不彻底清理)
|
|
||||||
*/
|
*/
|
||||||
@SuppressLint("UnsafeOptInUsageError")
|
@SuppressLint("UnsafeOptInUsageError")
|
||||||
class HttpReadAloudService : BaseReadAloudService(),
|
class HttpReadAloudService : BaseReadAloudService(),
|
||||||
@@ -78,7 +76,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
ExoPlayer.Builder(this).build()
|
ExoPlayer.Builder(this).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 【修改点1】改为外部存储,方便你查看文件,确认是否生成
|
// 改为外部存储
|
||||||
private val ttsFolderPath: String by lazy {
|
private val ttsFolderPath: String by lazy {
|
||||||
val baseDir = externalCacheDir ?: cacheDir
|
val baseDir = externalCacheDir ?: cacheDir
|
||||||
baseDir.absolutePath + File.separator + "httpTTS" + File.separator
|
baseDir.absolutePath + File.separator + "httpTTS" + File.separator
|
||||||
@@ -454,13 +452,10 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【核心修复点】生成音频文件名
|
* 生成音频文件名
|
||||||
* 1. 之前的问题:textChapter.title 可能是 "第一章 内容" (带格式),而数据库里是 "第一章 内容" (不带格式)。
|
|
||||||
* 2. 现在的做法:强制使用 textChapter.chapter.title (数据库原始标题)。
|
|
||||||
* 3. 结果:前台 (播放) 和后台 (下载) 用的标题来源完全一致,MD5 绝对匹配,不会再重复下载了!
|
|
||||||
*/
|
*/
|
||||||
private fun md5SpeakFileName(content: String, textChapter: TextChapter? = this.textChapter): String {
|
private fun md5SpeakFileName(content: String, textChapter: TextChapter? = this.textChapter): String {
|
||||||
val titleToUse = textChapter?.chapter?.title ?: "" // 强制取“核芯”标题
|
val titleToUse = textChapter?.chapter?.title ?: ""
|
||||||
return MD5Utils.md5Encode16(titleToUse) + "_" +
|
return MD5Utils.md5Encode16(titleToUse) + "_" +
|
||||||
MD5Utils.md5Encode16("${ReadAloud.httpTTS?.url}-|-$speechRate-|-$content")
|
MD5Utils.md5Encode16("${ReadAloud.httpTTS?.url}-|-$speechRate-|-$content")
|
||||||
}
|
}
|
||||||
@@ -492,7 +487,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 移除缓存文件
|
* 移除缓存文件
|
||||||
* 修复逻辑:如果时间设置为0,则不再保护当前章节,退出即全删。
|
* 如果时间设置为0,则不再保护当前章节,退出即全删。
|
||||||
*/
|
*/
|
||||||
private fun removeCacheFile() {
|
private fun removeCacheFile() {
|
||||||
val keepTime = AppConfig.audioCacheCleanTime
|
val keepTime = AppConfig.audioCacheCleanTime
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.legado.app.service
|
package io.legado.app.service
|
||||||
|
|
||||||
|
// ——————【新增引用】——————
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -21,6 +22,7 @@ import io.legado.app.utils.getPrefBoolean
|
|||||||
import io.legado.app.utils.getPrefInt
|
import io.legado.app.utils.getPrefInt
|
||||||
import io.legado.app.utils.postEvent
|
import io.legado.app.utils.postEvent
|
||||||
import io.legado.app.utils.printOnDebug
|
import io.legado.app.utils.printOnDebug
|
||||||
|
import io.legado.app.utils.putPrefBoolean
|
||||||
import io.legado.app.utils.sendToClip
|
import io.legado.app.utils.sendToClip
|
||||||
import io.legado.app.utils.servicePendingIntent
|
import io.legado.app.utils.servicePendingIntent
|
||||||
import io.legado.app.utils.startForegroundServiceCompat
|
import io.legado.app.utils.startForegroundServiceCompat
|
||||||
@@ -33,8 +35,6 @@ import splitties.init.appCtx
|
|||||||
import splitties.systemservices.powerManager
|
import splitties.systemservices.powerManager
|
||||||
import splitties.systemservices.wifiManager
|
import splitties.systemservices.wifiManager
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
// ——————【新增引用】——————
|
|
||||||
import io.legado.app.utils.putPrefBoolean
|
|
||||||
|
|
||||||
class WebService : BaseService() {
|
class WebService : BaseService() {
|
||||||
|
|
||||||
@@ -43,9 +43,6 @@ class WebService : BaseService() {
|
|||||||
var hostAddress = ""
|
var hostAddress = ""
|
||||||
|
|
||||||
fun start(context: Context) {
|
fun start(context: Context) {
|
||||||
// ——————【修改开始】记录开启状态——————
|
|
||||||
appCtx.putPrefBoolean("web_service_auto", true)
|
|
||||||
// ——————【修改结束】——————
|
|
||||||
context.startService<WebService>()
|
context.startService<WebService>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +52,6 @@ class WebService : BaseService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun stop(context: Context) {
|
fun stop(context: Context) {
|
||||||
// ——————【修改开始】记录关闭状态——————
|
|
||||||
appCtx.putPrefBoolean("web_service_auto", false)
|
|
||||||
// ——————【修改结束】——————
|
|
||||||
context.stopService<WebService>()
|
context.stopService<WebService>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package io.legado.app.ui.book.read.config
|
package io.legado.app.ui.book.read.config
|
||||||
|
|
||||||
|
//import io.legado.app.lib.theme.backgroundColor
|
||||||
|
//import io.legado.app.lib.theme.primaryColor
|
||||||
|
// 【新增引用】为了显示清理成功的提示
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -18,16 +21,16 @@ import io.legado.app.help.config.AppConfig
|
|||||||
import io.legado.app.lib.dialogs.SelectItem
|
import io.legado.app.lib.dialogs.SelectItem
|
||||||
import io.legado.app.lib.prefs.SwitchPreference
|
import io.legado.app.lib.prefs.SwitchPreference
|
||||||
import io.legado.app.lib.prefs.fragment.PreferenceFragment
|
import io.legado.app.lib.prefs.fragment.PreferenceFragment
|
||||||
//import io.legado.app.lib.theme.backgroundColor
|
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.model.ReadAloud
|
import io.legado.app.model.ReadAloud
|
||||||
import io.legado.app.service.BaseReadAloudService
|
import io.legado.app.service.BaseReadAloudService
|
||||||
|
import io.legado.app.ui.widget.number.NumberPickerDialog
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
import io.legado.app.utils.StringUtils
|
import io.legado.app.utils.StringUtils
|
||||||
|
import io.legado.app.utils.TTSCacheUtils
|
||||||
import io.legado.app.utils.fromJsonObject
|
import io.legado.app.utils.fromJsonObject
|
||||||
import io.legado.app.utils.postEvent
|
import io.legado.app.utils.postEvent
|
||||||
|
import io.legado.app.utils.putPrefInt
|
||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
// 【新增引用】为了显示清理成功的提示
|
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
|
|
||||||
class ReadAloudConfigDialog : BasePrefDialogFragment() {
|
class ReadAloudConfigDialog : BasePrefDialogFragment() {
|
||||||
@@ -73,17 +76,16 @@ class ReadAloudConfigDialog : BasePrefDialogFragment() {
|
|||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
addPreferencesFromResource(R.xml.pref_config_aloud)
|
addPreferencesFromResource(R.xml.pref_config_aloud)
|
||||||
upSpeakEngineSummary()
|
upSpeakEngineSummary()
|
||||||
|
upPreferenceSummary(PreferKey.audioPreDownloadNum)
|
||||||
|
upPreferenceSummary(PreferKey.audioCacheCleanTime)
|
||||||
findPreference<SwitchPreference>(PreferKey.pauseReadAloudWhilePhoneCalls)?.let {
|
findPreference<SwitchPreference>(PreferKey.pauseReadAloudWhilePhoneCalls)?.let {
|
||||||
it.isEnabled = AppConfig.ignoreAudioFocus
|
it.isEnabled = AppConfig.ignoreAudioFocus
|
||||||
}
|
}
|
||||||
|
|
||||||
// 【新增代码】绑定清理缓存按钮事件
|
|
||||||
findPreference<Preference>("clear_cache")?.let {
|
findPreference<Preference>("clear_cache")?.let {
|
||||||
it.summary = getString(R.string.clear_cache)
|
it.summary = getString(R.string.clear_cache)
|
||||||
it.setOnPreferenceClickListener {
|
it.setOnPreferenceClickListener {
|
||||||
// 调用 AppConfig 中的万能清理函数 (自动处理外部存储)
|
TTSCacheUtils.clearTtsCache()
|
||||||
AppConfig.clearTtsCache()
|
|
||||||
// 弹出提示
|
|
||||||
toastOnUi("音频缓存已清理")
|
toastOnUi("音频缓存已清理")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@@ -107,6 +109,38 @@ class ReadAloudConfigDialog : BasePrefDialogFragment() {
|
|||||||
|
|
||||||
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||||
when (preference.key) {
|
when (preference.key) {
|
||||||
|
PreferKey.audioPreDownloadNum -> {
|
||||||
|
NumberPickerDialog(requireContext())
|
||||||
|
.setTitle(getString(R.string.read_aloud_preload))
|
||||||
|
.setMaxValue(50)
|
||||||
|
.setMinValue(0)
|
||||||
|
.setValue(10)
|
||||||
|
.setCustomButton((R.string.btn_default_s)) {
|
||||||
|
putPrefInt(PreferKey.audioPreDownloadNum, 10)
|
||||||
|
upPreferenceSummary(PreferKey.audioPreDownloadNum)
|
||||||
|
}
|
||||||
|
.show {
|
||||||
|
putPrefInt(PreferKey.audioPreDownloadNum, it)
|
||||||
|
upPreferenceSummary(PreferKey.audioPreDownloadNum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferKey.audioCacheCleanTime -> {
|
||||||
|
NumberPickerDialog(requireContext())
|
||||||
|
.setTitle(getString(R.string.audio_cache_clean_time))
|
||||||
|
.setMaxValue(50)
|
||||||
|
.setMinValue(0)
|
||||||
|
.setValue(1)
|
||||||
|
.setCustomButton((R.string.btn_default_s)) {
|
||||||
|
putPrefInt(PreferKey.audioCacheCleanTime, 10)
|
||||||
|
upPreferenceSummary(PreferKey.audioCacheCleanTime)
|
||||||
|
}
|
||||||
|
.show {
|
||||||
|
putPrefInt(PreferKey.audioCacheCleanTime, it)
|
||||||
|
upPreferenceSummary(PreferKey.audioCacheCleanTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PreferKey.ttsEngine -> showDialogFragment(SpeakEngineDialog())
|
PreferKey.ttsEngine -> showDialogFragment(SpeakEngineDialog())
|
||||||
"sysTtsConfig" -> IntentHelp.openTTSSetting()
|
"sysTtsConfig" -> IntentHelp.openTTSSetting()
|
||||||
}
|
}
|
||||||
@@ -139,12 +173,34 @@ class ReadAloudConfigDialog : BasePrefDialogFragment() {
|
|||||||
preference.summary = if (index >= 0) preference.entries[index] else null
|
preference.summary = if (index >= 0) preference.entries[index] else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
preference?.summary = value
|
preference?.summary = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun upPreferenceSummary(preferenceKey: String, value: String? = null) {
|
||||||
|
val preference = findPreference<Preference>(preferenceKey) ?: return
|
||||||
|
when (preferenceKey) {
|
||||||
|
PreferKey.audioPreDownloadNum -> {
|
||||||
|
preference.summary = getString(
|
||||||
|
R.string.read_aloud_preload_summary,
|
||||||
|
AppConfig.audioPreDownloadNum
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferKey.audioCacheCleanTime -> {
|
||||||
|
preference.summary = getString(
|
||||||
|
R.string.audio_cache_clean_time_summary,
|
||||||
|
AppConfig.audioCacheCleanTimeOrgin
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> preference.summary = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun upSpeakEngineSummary() {
|
override fun upSpeakEngineSummary() {
|
||||||
upPreferenceSummary(
|
upPreferenceSummary(
|
||||||
findPreference(PreferKey.ttsEngine),
|
findPreference(PreferKey.ttsEngine),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.legado.app.ui.book.read.config
|
package io.legado.app.ui.book.read.config
|
||||||
|
|
||||||
|
//import io.legado.app.lib.theme.primaryColor
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@@ -24,15 +25,14 @@ import io.legado.app.help.DirectLinkUpload
|
|||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.lib.dialogs.SelectItem
|
import io.legado.app.lib.dialogs.SelectItem
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.model.ReadAloud
|
import io.legado.app.model.ReadAloud
|
||||||
import io.legado.app.model.ReadBook
|
import io.legado.app.model.ReadBook
|
||||||
import io.legado.app.ui.association.ImportHttpTtsDialog
|
import io.legado.app.ui.association.ImportHttpTtsDialog
|
||||||
import io.legado.app.ui.file.HandleFileContract
|
import io.legado.app.ui.file.HandleFileContract
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.utils.ACache
|
import io.legado.app.utils.ACache
|
||||||
import io.legado.app.utils.FileUtils
|
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
|
import io.legado.app.utils.TTSCacheUtils
|
||||||
import io.legado.app.utils.fromJsonObject
|
import io.legado.app.utils.fromJsonObject
|
||||||
import io.legado.app.utils.gone
|
import io.legado.app.utils.gone
|
||||||
import io.legado.app.utils.isAbsUrl
|
import io.legado.app.utils.isAbsUrl
|
||||||
@@ -49,7 +49,6 @@ import kotlinx.coroutines.flow.catch
|
|||||||
import kotlinx.coroutines.flow.conflate
|
import kotlinx.coroutines.flow.conflate
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tts引擎管理
|
* tts引擎管理
|
||||||
@@ -236,19 +235,10 @@ class SpeakEngineDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_recycl
|
|||||||
adapter.notifyItemRangeChanged(adapter.getHeaderCount(), adapter.itemCount)
|
adapter.notifyItemRangeChanged(adapter.getHeaderCount(), adapter.itemCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 【核心修改点】清理缓存方法
|
|
||||||
* 原来:只删除 cacheDir (内部存储)
|
|
||||||
* 现在:调用 AppConfig.clearTtsCache(),自动处理 externalCacheDir (外部存储)
|
|
||||||
*/
|
|
||||||
fun clearCache() {
|
fun clearCache() {
|
||||||
execute {
|
execute {
|
||||||
ReadAloud.upReadAloudClass()
|
ReadAloud.upReadAloudClass()
|
||||||
|
TTSCacheUtils.clearTtsCache()
|
||||||
// 调用万能清理函数
|
|
||||||
AppConfig.clearTtsCache()
|
|
||||||
|
|
||||||
// 显示成功提示
|
|
||||||
toastOnUi(R.string.clear_cache_success)
|
toastOnUi(R.string.clear_cache_success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import io.legado.app.help.coroutine.Coroutine
|
|||||||
import io.legado.app.help.storage.Backup
|
import io.legado.app.help.storage.Backup
|
||||||
import io.legado.app.help.update.AppUpdateGitHub
|
import io.legado.app.help.update.AppUpdateGitHub
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
|
import io.legado.app.service.WebService
|
||||||
import io.legado.app.ui.about.CrashLogsDialog
|
import io.legado.app.ui.about.CrashLogsDialog
|
||||||
import io.legado.app.ui.about.UpdateDialog
|
import io.legado.app.ui.about.UpdateDialog
|
||||||
import io.legado.app.ui.book.read.ReadBookActivity
|
import io.legado.app.ui.book.read.ReadBookActivity
|
||||||
@@ -71,7 +72,6 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
import io.legado.app.service.WebService
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主界面
|
* 主界面
|
||||||
@@ -135,13 +135,11 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
binding.viewPagerMain.fitsSystemWindows = true
|
binding.viewPagerMain.fitsSystemWindows = true
|
||||||
// 其他初始化逻辑
|
// 其他初始化逻辑
|
||||||
setupBackCallback()
|
setupBackCallback()
|
||||||
|
|
||||||
// ——————【修改开始】——————
|
|
||||||
// 智能自启:如果上次是手动开启状态(web_service_auto 为 true),则自启
|
// 智能自启:如果上次是手动开启状态(web_service_auto 为 true),则自启
|
||||||
if (getPrefBoolean("web_service_auto", false)) {
|
if (AppConfig.webServiceAutoStart) {
|
||||||
WebService.startForeground(this)
|
WebService.startForeground(this)
|
||||||
}
|
}
|
||||||
// ——————【修改结束】——————
|
|
||||||
|
|
||||||
upBottomMenu()
|
upBottomMenu()
|
||||||
initView()
|
initView()
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package io.legado.app.utils
|
||||||
|
|
||||||
|
import splitties.init.appCtx
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object TTSCacheUtils {
|
||||||
|
|
||||||
|
fun clearTtsCache() {
|
||||||
|
val baseDir = appCtx.externalCacheDir ?: appCtx.cacheDir
|
||||||
|
// 清理音频文件
|
||||||
|
FileUtils.delete(baseDir.absolutePath + File.separator + "httpTTS")
|
||||||
|
// 清理数据库索引 (可选,建议一起清,防止索引还在但文件没了)
|
||||||
|
FileUtils.delete(baseDir.absolutePath + File.separator + "httpTTS_cache")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1370,4 +1370,9 @@
|
|||||||
<string name="palette_style">调色板样式</string>
|
<string name="palette_style">调色板样式</string>
|
||||||
<string name="tip_compose_set">这里的选项仅可以控制使用Compose重写的界面。</string>
|
<string name="tip_compose_set">这里的选项仅可以控制使用Compose重写的界面。</string>
|
||||||
<string name="is_blur_enable">启用控件模糊</string>
|
<string name="is_blur_enable">启用控件模糊</string>
|
||||||
|
<string name="web_service_auto_start">启动应用时打开Web服务</string>
|
||||||
|
<string name="read_aloud_preload">听书预加载数量</string>
|
||||||
|
<string name="read_aloud_preload_summary">%d</string>
|
||||||
|
<string name="audio_cache_clean_time">音频缓存保留时间(分钟)</string>
|
||||||
|
<string name="audio_cache_clean_time_summary">当前%d, 输入 0 代表退出即刻清理。</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1375,4 +1375,9 @@
|
|||||||
<string name="palette_style">调色板样式</string>
|
<string name="palette_style">调色板样式</string>
|
||||||
<string name="tip_compose_set">这里的选项仅可以控制使用Compose重写的界面。</string>
|
<string name="tip_compose_set">这里的选项仅可以控制使用Compose重写的界面。</string>
|
||||||
<string name="is_blur_enable">启用控件模糊</string>
|
<string name="is_blur_enable">启用控件模糊</string>
|
||||||
|
<string name="web_service_auto_start">启动应用时打开Web服务</string>
|
||||||
|
<string name="read_aloud_preload">听书预加载数量</string>
|
||||||
|
<string name="read_aloud_preload_summary">%d</string>
|
||||||
|
<string name="audio_cache_clean_time">音频缓存保留时间(分钟)</string>
|
||||||
|
<string name="audio_cache_clean_time_summary">当前%d, 输入 0 代表退出即刻清理。</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -67,22 +67,16 @@
|
|||||||
android:key="sysTtsConfig"
|
android:key="sysTtsConfig"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
<io.legado.app.lib.prefs.EditTextPreference
|
<io.legado.app.lib.prefs.Preference
|
||||||
android:key="audioPreDownloadNum"
|
android:key="audioPreDownloadNum"
|
||||||
android:title="听书预加载数量(章节)"
|
android:summary="@string/read_aloud_preload_summary"
|
||||||
android:summary="设置听书时预先下载的章节数量"
|
android:title="@string/read_aloud_preload"
|
||||||
android:defaultValue="10"
|
|
||||||
android:inputType="number"
|
|
||||||
android:persistent="true"
|
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
<io.legado.app.lib.prefs.EditTextPreference
|
<io.legado.app.lib.prefs.Preference
|
||||||
android:key="audioCacheCleanTime"
|
android:key="audioCacheCleanTime"
|
||||||
android:title="音频缓存保留时间(分钟)"
|
android:summary="@string/audio_cache_clean_time_summary"
|
||||||
android:summary="听书缓存文件保留多久后自动删除(单位:分钟)。输入 0 代表退出即刻清理。"
|
android:title="@string/audio_cache_clean_time"
|
||||||
android:defaultValue="10"
|
|
||||||
android:inputType="number"
|
|
||||||
android:persistent="true"
|
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
</io.legado.app.lib.prefs.PreferenceCategory>
|
</io.legado.app.lib.prefs.PreferenceCategory>
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,12 @@
|
|||||||
app:entries="@array/default_app_variant"
|
app:entries="@array/default_app_variant"
|
||||||
app:entryValues="@array/default_app_variant_value" />
|
app:entryValues="@array/default_app_variant_value" />
|
||||||
|
|
||||||
|
<io.legado.app.lib.prefs.SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="webServiceAutoStart"
|
||||||
|
android:title="@string/web_service_auto_start"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
<io.legado.app.lib.prefs.PreferenceCategory
|
<io.legado.app.lib.prefs.PreferenceCategory
|
||||||
android:title="@string/main_activity"
|
android:title="@string/main_activity"
|
||||||
app:allowDividerAbove="false"
|
app:allowDividerAbove="false"
|
||||||
|
|||||||
Reference in new issue
Block a user