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

@ -8,8 +8,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.graphics.BitmapFactory
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.PlaybackStateCompat
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.postEvent
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
abstract class BaseReadAloudService : BaseService(),
@ -44,7 +46,6 @@ abstract class BaseReadAloudService : BaseService(),
}
}
internal val handler = Handler(Looper.getMainLooper())
private lateinit var audioManager: AudioManager
private var mFocusRequest: AudioFocusRequestCompat? = null
private var broadcastReceiver: BroadcastReceiver? = null
@ -56,7 +57,7 @@ abstract class BaseReadAloudService : BaseService(),
internal var readAloudNumber: Int = 0
internal var textChapter: TextChapter? = null
internal var pageIndex = 0
private val dsRunnable: Runnable = Runnable { doDs() }
private var dsJob: Job? = null
override fun onCreate() {
super.onCreate()
@ -69,7 +70,7 @@ abstract class BaseReadAloudService : BaseService(),
initBroadcastReceiver()
upNotification()
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
startDs()
doDs()
}
override fun onDestroy() {
@ -149,7 +150,7 @@ abstract class BaseReadAloudService : BaseService(),
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED)
postEvent(EventBus.ALOUD_STATE, Status.PAUSE)
ReadBook.uploadProgress()
startDs()
doDs()
}
@CallSuper
@ -184,7 +185,7 @@ abstract class BaseReadAloudService : BaseService(),
private fun setTimer(minute: Int) {
timeMinute = minute
startDs()
doDs()
}
private fun addTimer() {
@ -194,32 +195,34 @@ abstract class BaseReadAloudService : BaseService(),
timeMinute += 10
if (timeMinute > 180) timeMinute = 180
}
startDs()
}
private fun startDs() {
postEvent(EventBus.TTS_DS, timeMinute)
upNotification()
handler.removeCallbacks(dsRunnable)
handler.postDelayed(dsRunnable, 60000)
doDs()
}
/**
* 定时
*/
@Synchronized
private fun doDs() {
handler.removeCallbacks(dsRunnable)
if (!pause) {
if (timeMinute >= 0) {
timeMinute--
}
if (timeMinute == 0) {
ReadAloud.stop(this)
}
}
postEvent(EventBus.TTS_DS, timeMinute)
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.service.help.ReadAloud
import io.legado.app.utils.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileDescriptor
import java.io.FileInputStream
@ -238,7 +240,8 @@ class HttpReadAloudService : BaseReadAloudService(),
if (what == -38 && extra == 0) {
return true
}
handler.postDelayed({
launch {
delay(100)
readAloudNumber += contentList[nowSpeak].length + 1
if (nowSpeak < contentList.lastIndex) {
nowSpeak++
@ -246,7 +249,7 @@ class HttpReadAloudService : BaseReadAloudService(),
} else {
nextChapter()
}
}, 50)
}
return true
}

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