|
|
@ -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 |
|
|
|
|
|
|
|
|
|
|
|