Merge remote-tracking branch 'origin/master'

pull/1276/head
ag2s20150909 3 years ago
commit 79978db56c
  1. 5
      app/src/main/java/io/legado/app/api/controller/SourceController.kt
  2. 53
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  3. 7
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  4. 102
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@ -5,9 +5,9 @@ import android.text.TextUtils
import io.legado.app.api.ReturnData import io.legado.app.api.ReturnData
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.BookSourceAnalyzer
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonArray
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.msg import io.legado.app.utils.msg
object SourceController { object SourceController {
@ -23,8 +23,9 @@ object SourceController {
fun saveSource(postData: String?): ReturnData { fun saveSource(postData: String?): ReturnData {
val returnData = ReturnData() val returnData = ReturnData()
postData ?: return returnData.setErrorMsg("数据不能为空")
kotlin.runCatching { kotlin.runCatching {
val bookSource = GSON.fromJsonObject<BookSource>(postData) val bookSource = BookSourceAnalyzer.jsonToBookSource(postData)
if (bookSource != null) { if (bookSource != null) {
if (TextUtils.isEmpty(bookSource.bookSourceName) || TextUtils.isEmpty(bookSource.bookSourceUrl)) { if (TextUtils.isEmpty(bookSource.bookSourceName) || TextUtils.isEmpty(bookSource.bookSourceUrl)) {
returnData.setErrorMsg("书源名称和URL不能为空") returnData.setErrorMsg("书源名称和URL不能为空")

@ -8,8 +8,6 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.AudioManager import android.media.AudioManager
import android.os.Handler
import android.os.Looper
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
@ -29,6 +27,10 @@ import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import splitties.init.appCtx import splitties.init.appCtx
abstract class BaseReadAloudService : BaseService(), abstract class BaseReadAloudService : BaseService(),
@ -44,7 +46,6 @@ abstract class BaseReadAloudService : BaseService(),
} }
} }
internal val handler = Handler(Looper.getMainLooper())
private lateinit var audioManager: AudioManager private lateinit var audioManager: AudioManager
private var mFocusRequest: AudioFocusRequestCompat? = null private var mFocusRequest: AudioFocusRequestCompat? = null
private var broadcastReceiver: BroadcastReceiver? = null private var broadcastReceiver: BroadcastReceiver? = null
@ -56,7 +57,7 @@ abstract class BaseReadAloudService : BaseService(),
internal var readAloudNumber: Int = 0 internal var readAloudNumber: Int = 0
internal var textChapter: TextChapter? = null internal var textChapter: TextChapter? = null
internal var pageIndex = 0 internal var pageIndex = 0
private val dsRunnable: Runnable = Runnable { doDs() } private var dsJob: Job? = null
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@ -69,7 +70,7 @@ abstract class BaseReadAloudService : BaseService(),
initBroadcastReceiver() initBroadcastReceiver()
upNotification() upNotification()
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING) upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
startDs() doDs()
} }
override fun onDestroy() { override fun onDestroy() {
@ -149,7 +150,7 @@ abstract class BaseReadAloudService : BaseService(),
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED) upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED)
postEvent(EventBus.ALOUD_STATE, Status.PAUSE) postEvent(EventBus.ALOUD_STATE, Status.PAUSE)
ReadBook.uploadProgress() ReadBook.uploadProgress()
startDs() doDs()
} }
@CallSuper @CallSuper
@ -184,7 +185,7 @@ abstract class BaseReadAloudService : BaseService(),
private fun setTimer(minute: Int) { private fun setTimer(minute: Int) {
timeMinute = minute timeMinute = minute
startDs() doDs()
} }
private fun addTimer() { private fun addTimer() {
@ -194,32 +195,34 @@ abstract class BaseReadAloudService : BaseService(),
timeMinute += 10 timeMinute += 10
if (timeMinute > 180) timeMinute = 180 if (timeMinute > 180) timeMinute = 180
} }
startDs() doDs()
}
private fun startDs() {
postEvent(EventBus.TTS_DS, timeMinute)
upNotification()
handler.removeCallbacks(dsRunnable)
handler.postDelayed(dsRunnable, 60000)
} }
/** /**
* 定时 * 定时
*/ */
@Synchronized
private fun doDs() { private fun doDs() {
handler.removeCallbacks(dsRunnable)
if (!pause) {
if (timeMinute >= 0) {
timeMinute--
}
if (timeMinute == 0) {
ReadAloud.stop(this)
}
}
postEvent(EventBus.TTS_DS, timeMinute) postEvent(EventBus.TTS_DS, timeMinute)
upNotification() upNotification()
handler.postDelayed(dsRunnable, 60000) dsJob?.cancel()
dsJob = launch {
while (isActive) {
delay(60000)
if (isActive) {
if (!pause) {
if (timeMinute >= 0) {
timeMinute--
}
if (timeMinute == 0) {
ReadAloud.stop(this@BaseReadAloudService)
}
}
postEvent(EventBus.TTS_DS, timeMinute)
upNotification()
}
}
}
} }
/** /**

@ -10,8 +10,10 @@ import io.legado.app.model.ReadBook
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.io.FileDescriptor import java.io.FileDescriptor
import java.io.FileInputStream import java.io.FileInputStream
@ -238,7 +240,8 @@ class HttpReadAloudService : BaseReadAloudService(),
if (what == -38 && extra == 0) { if (what == -38 && extra == 0) {
return true return true
} }
handler.postDelayed({ launch {
delay(100)
readAloudNumber += contentList[nowSpeak].length + 1 readAloudNumber += contentList[nowSpeak].length + 1
if (nowSpeak < contentList.lastIndex) { if (nowSpeak < contentList.lastIndex) {
nowSpeak++ nowSpeak++
@ -246,7 +249,7 @@ class HttpReadAloudService : BaseReadAloudService(),
} else { } else {
nextChapter() nextChapter()
} }
}, 50) }
return true return true
} }

@ -5,8 +5,6 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.* import android.view.*
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@ -53,7 +51,9 @@ import io.legado.app.ui.replace.edit.ReplaceEditActivity
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class ReadBookActivity : ReadBookBaseActivity(), class ReadBookActivity : ReadBookBaseActivity(),
@ -109,15 +109,9 @@ class ReadBookActivity : ReadBookBaseActivity(),
override val isInitFinish: Boolean get() = viewModel.isInitFinish override val isInitFinish: Boolean get() = viewModel.isInitFinish
override val isScroll: Boolean get() = binding.readView.isScroll override val isScroll: Boolean get() = binding.readView.isScroll
private val mHandler = Handler(Looper.getMainLooper()) private var keepScreenJon: Job? = null
private val keepScreenRunnable = Runnable { keepScreenOn(false) } private var autoPageJob: Job? = null
private val autoPageRunnable = Runnable { autoPagePlus() } private var backupJob: Job? = null
private val backupRunnable = Runnable {
if (!BuildConfig.DEBUG) {
ReadBook.uploadProgress()
Backup.autoBack(this)
}
}
override var autoPageProgress = 0 override var autoPageProgress = 0
override var isAutoPage = false override var isAutoPage = false
private var screenTimeOut: Long = 0 private var screenTimeOut: Long = 0
@ -169,7 +163,7 @@ class ReadBookActivity : ReadBookBaseActivity(),
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
autoPageStop() autoPageStop()
mHandler.removeCallbacks(backupRunnable) backupJob?.cancel()
ReadBook.saveRead() ReadBook.saveRead()
timeBatteryReceiver?.let { timeBatteryReceiver?.let {
unregisterReceiver(it) unregisterReceiver(it)
@ -629,7 +623,7 @@ class ReadBookActivity : ReadBookBaseActivity(),
launch { launch {
autoPageProgress = 0 autoPageProgress = 0
binding.readMenu.setSeekPage(ReadBook.durPageIndex()) binding.readMenu.setSeekPage(ReadBook.durPageIndex())
mHandler.postDelayed(backupRunnable, 600000) startBackupJob()
} }
} }
@ -692,38 +686,43 @@ class ReadBookActivity : ReadBookBaseActivity(),
override fun autoPageStop() { override fun autoPageStop() {
if (isAutoPage) { if (isAutoPage) {
isAutoPage = false isAutoPage = false
mHandler.removeCallbacks(autoPageRunnable) autoPageJob?.cancel()
binding.readView.invalidate()
binding.readMenu.setAutoPage(false) binding.readMenu.setAutoPage(false)
upScreenTimeOut() upScreenTimeOut()
} }
} }
private fun autoPagePlus() { private fun autoPagePlus() {
var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height autoPageJob?.cancel()
var scrollOffset = 1 autoPageJob = launch {
if (delayMillis < 20) { while (isActive) {
var delayInt = delayMillis.toInt() var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height
if (delayInt == 0) delayInt = 1 var scrollOffset = 1
scrollOffset = 20 / delayInt if (delayMillis < 20) {
delayMillis = 20 var delayInt = delayMillis.toInt()
} if (delayInt == 0) delayInt = 1
mHandler.removeCallbacks(autoPageRunnable) scrollOffset = 20 / delayInt
if (!menuLayoutIsVisible) { delayMillis = 20
if (binding.readView.isScroll) { }
binding.readView.curPage.scroll(-scrollOffset) delay(delayMillis)
} else { if (!menuLayoutIsVisible && isActive) {
autoPageProgress += scrollOffset if (binding.readView.isScroll) {
if (autoPageProgress >= binding.readView.height) { binding.readView.curPage.scroll(-scrollOffset)
autoPageProgress = 0 } else {
if (!binding.readView.fillPage(PageDirection.NEXT)) { autoPageProgress += scrollOffset
autoPageStop() if (autoPageProgress >= binding.readView.height) {
autoPageProgress = 0
if (!binding.readView.fillPage(PageDirection.NEXT)) {
autoPageStop()
}
} else {
binding.readView.invalidate()
}
} }
} else {
binding.readView.invalidate()
} }
} }
} }
mHandler.postDelayed(autoPageRunnable, delayMillis)
} }
override fun openSourceEditActivity() { override fun openSourceEditActivity() {
@ -878,6 +877,13 @@ class ReadBookActivity : ReadBookBaseActivity(),
} }
} }
private fun startBackupJob() {
backupJob?.cancel()
backupJob = launch {
delay(120000)
}
}
override fun finish() { override fun finish() {
ReadBook.book?.let { ReadBook.book?.let {
if (!ReadBook.inBookshelf) { if (!ReadBook.inBookshelf) {
@ -897,7 +903,6 @@ class ReadBookActivity : ReadBookBaseActivity(),
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
mHandler.removeCallbacks(keepScreenRunnable)
textActionMenu.dismiss() textActionMenu.dismiss()
binding.readView.onDestroy() binding.readView.onDestroy()
ReadBook.msg = null ReadBook.msg = null
@ -975,17 +980,20 @@ class ReadBookActivity : ReadBookBaseActivity(),
* 重置黑屏时间 * 重置黑屏时间
*/ */
override fun screenOffTimerStart() { override fun screenOffTimerStart() {
if (screenTimeOut < 0) { keepScreenJon?.cancel()
keepScreenOn(true) keepScreenJon = launch {
return if (screenTimeOut < 0) {
} keepScreenOn(true)
val t = screenTimeOut - sysScreenOffTime return@launch
if (t > 0) { }
mHandler.removeCallbacks(keepScreenRunnable) val t = screenTimeOut - sysScreenOffTime
keepScreenOn(true) if (t > 0) {
mHandler.postDelayed(keepScreenRunnable, screenTimeOut) keepScreenOn(true)
} else { delay(screenTimeOut)
keepScreenOn(false) keepScreenOn(false)
} else {
keepScreenOn(false)
}
} }
} }
} }
Loading…
Cancel
Save