长按菜单朗读从选择开始位置一直朗读下去,未完成

pull/2160/head
kunfei 2 years ago
parent 3a1ac902c3
commit a5fc04009e
  1. 5
      app/src/main/java/io/legado/app/model/ReadAloud.kt
  2. 2
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  3. 5
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  4. 65
      app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
  5. 4
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  6. 12
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  7. 4
      app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt

@ -38,11 +38,14 @@ object ReadAloud {
fun play( fun play(
context: Context, context: Context,
play: Boolean = true play: Boolean = true,
pageIndex: Int = ReadBook.durPageIndex
) { ) {
val intent = Intent(context, aloudClass) val intent = Intent(context, aloudClass)
intent.action = IntentAction.play intent.action = IntentAction.play
intent.putExtra("play", play) intent.putExtra("play", play)
intent.putExtra("pageIndex", pageIndex)
context.startService(intent) context.startService(intent)
} }

@ -102,7 +102,7 @@ abstract class BaseReadAloudService : BaseService(),
when (intent?.action) { when (intent?.action) {
IntentAction.play -> { IntentAction.play -> {
textChapter = ReadBook.curTextChapter textChapter = ReadBook.curTextChapter
pageIndex = ReadBook.durPageIndex pageIndex = intent.getIntExtra("pageIndex", ReadBook.durPageIndex)
newReadAloud( newReadAloud(
intent.getBooleanExtra("play", true) intent.getBooleanExtra("play", true)
) )

@ -609,13 +609,16 @@ class ReadBookActivity : BaseReadBookActivity(),
/** /**
* 当前选择的文本 * 当前选择的文本
*/ */
override val selectedText: String get() = binding.readView.curPage.selectedText override val selectedText: String get() = binding.readView.getSelectText()
/** /**
* 文本选择菜单操作 * 文本选择菜单操作
*/ */
override fun onMenuItemSelected(itemId: Int): Boolean { override fun onMenuItemSelected(itemId: Int): Boolean {
when (itemId) { when (itemId) {
R.id.menu_aloud -> {
ReadBook.readAloud()
}
R.id.menu_bookmark -> binding.readView.curPage.let { R.id.menu_bookmark -> binding.readView.curPage.let {
val bookmark = it.createBookmark() val bookmark = it.createBookmark()
if (bookmark == null) { if (bookmark == null) {

@ -7,8 +7,6 @@ import android.content.Intent
import android.content.pm.ResolveInfo import android.content.pm.ResolveInfo
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.view.* import android.view.*
import android.widget.PopupWindow import android.widget.PopupWindow
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
@ -22,13 +20,11 @@ import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.ItemTextBinding import io.legado.app.databinding.ItemTextBinding
import io.legado.app.databinding.PopupActionMenuBinding import io.legado.app.databinding.PopupActionMenuBinding
import io.legado.app.service.BaseReadAloudService
import io.legado.app.utils.* import io.legado.app.utils.*
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
class TextActionMenu(private val context: Context, private val callBack: CallBack) : class TextActionMenu(private val context: Context, private val callBack: CallBack) :
PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT), PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
TextToSpeech.OnInitListener {
private val binding = PopupActionMenuBinding.inflate(LayoutInflater.from(context)) private val binding = PopupActionMenuBinding.inflate(LayoutInflater.from(context))
private val adapter = Adapter(context).apply { private val adapter = Adapter(context).apply {
@ -37,9 +33,6 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
private val menuItems: List<MenuItemImpl> private val menuItems: List<MenuItemImpl>
private val visibleMenuItems = arrayListOf<MenuItemImpl>() private val visibleMenuItems = arrayListOf<MenuItemImpl>()
private val moreMenuItems = arrayListOf<MenuItemImpl>() private val moreMenuItems = arrayListOf<MenuItemImpl>()
private val ttsListener by lazy {
TTSUtteranceListener()
}
private val expandTextMenu get() = context.getPrefBoolean(PreferKey.expandTextMenu) private val expandTextMenu get() = context.getPrefBoolean(PreferKey.expandTextMenu)
init { init {
@ -194,13 +187,6 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
when (item.itemId) { when (item.itemId) {
R.id.menu_copy -> context.sendToClip(callBack.selectedText) R.id.menu_copy -> context.sendToClip(callBack.selectedText)
R.id.menu_share_str -> context.share(callBack.selectedText) R.id.menu_share_str -> context.share(callBack.selectedText)
R.id.menu_aloud -> {
if (BaseReadAloudService.isRun) {
context.toastOnUi(R.string.alouding_disable)
return
}
readAloud(callBack.selectedText)
}
R.id.menu_browser -> { R.id.menu_browser -> {
kotlin.runCatching { kotlin.runCatching {
val intent = if (callBack.selectedText.isAbsUrl()) { val intent = if (callBack.selectedText.isAbsUrl()) {
@ -227,38 +213,6 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
} }
} }
private var textToSpeech: TextToSpeech? = null
private var ttsInitFinish = false
private var lastText: String = ""
@SuppressLint("SetJavaScriptEnabled")
private fun readAloud(text: String) {
lastText = text
if (textToSpeech == null) {
textToSpeech = TextToSpeech(context, this).apply {
setOnUtteranceProgressListener(ttsListener)
}
return
}
if (!ttsInitFinish) return
if (text == "") return
if (textToSpeech?.isSpeaking == true) {
textToSpeech?.stop()
}
textToSpeech?.speak(text, TextToSpeech.QUEUE_ADD, null, "select_text")
lastText = ""
}
@Synchronized
override fun onInit(status: Int) {
if (status == TextToSpeech.SUCCESS) {
ttsInitFinish = true
readAloud(lastText)
} else {
context.toastOnUi(R.string.tts_init_failed)
}
}
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
private fun createProcessTextIntent(): Intent { private fun createProcessTextIntent(): Intent {
return Intent() return Intent()
@ -299,23 +253,6 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
} }
} }
private inner class TTSUtteranceListener : UtteranceProgressListener() {
override fun onStart(utteranceId: String?) {
}
override fun onDone(utteranceId: String?) {
textToSpeech?.shutdown()
textToSpeech = null
}
@Deprecated("Deprecated in Java")
override fun onError(utteranceId: String?) {
}
}
interface CallBack { interface CallBack {
val selectedText: String val selectedText: String

@ -40,8 +40,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
private var callBack: CallBack private var callBack: CallBack
private val visibleRect = RectF() private val visibleRect = RectF()
private val selectStart = TextPos(0, 0, 0) val selectStart = TextPos(0, 0, 0)
private val selectEnd = TextPos(0, 0, 0) val selectEnd = TextPos(0, 0, 0)
var textPage: TextPage = TextPage() var textPage: TextPage = TextPage()
private set private set

@ -6,7 +6,6 @@ import android.view.LayoutInflater
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import io.legado.app.R
import io.legado.app.constant.AppConst.timeFormat import io.legado.app.constant.AppConst.timeFormat
import io.legado.app.data.entities.Bookmark import io.legado.app.data.entities.Bookmark
import io.legado.app.databinding.ViewBookPageBinding import io.legado.app.databinding.ViewBookPageBinding
@ -15,9 +14,13 @@ import io.legado.app.help.config.ReadTipConfig
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.ui.book.read.page.entities.TextPos
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.widget.BatteryView import io.legado.app.ui.widget.BatteryView
import io.legado.app.utils.* import io.legado.app.utils.activity
import io.legado.app.utils.dpToPx
import io.legado.app.utils.statusBarHeight
import io.legado.app.utils.visible
import splitties.views.backgroundColor import splitties.views.backgroundColor
import java.util.* import java.util.*
@ -308,7 +311,10 @@ class PageView(context: Context) : FrameLayout(context) {
return binding.contentTextView.relativePage(relativePagePos) return binding.contentTextView.relativePage(relativePagePos)
} }
val textPage get() = binding.contentTextView.textPage
val selectStart: TextPos get() = binding.contentTextView.selectStart
val selectedText: String get() = binding.contentTextView.getSelectedText() val selectedText: String get() = binding.contentTextView.getSelectedText()
val textPage get() = binding.contentTextView.textPage
} }

@ -531,6 +531,10 @@ class ReadView(context: Context, attrs: AttributeSet) :
nextPage.upBattery(battery) nextPage.upBattery(battery)
} }
fun getSelectText(): String {
return curPage.selectedText
}
override val currentChapter: TextChapter? override val currentChapter: TextChapter?
get() { get() {
return if (callBack.isInitFinish) ReadBook.textChapter(0) else null return if (callBack.isInitFinish) ReadBook.textChapter(0) else null

Loading…
Cancel
Save