长按菜单朗读从选择开始位置一直朗读下去,未完成
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user