使用布尔值自动 show/dismiss Kotlin 中的警报对话框

Automatically show/dismiss alert dialog in Kotlin with a bool

我正在创建一个文本转语音应用程序,并希望在 tts 对象说话时向扬声器显示一个对话框,并在完成后自动隐藏自己。有人有办法做到这一点吗?以下是我目前所处的位置,有什么想法吗?

private lateinit var textToSpeech: TextToSpeech
private lateinit var alertDialogBuilder: AlertDialog.Builder

class MainActivity : AppCompatActivity() {
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        alertDialogBuilder = AlertDialog.Builder(this)
        textToSpeech = TextToSpeech(applicationContext,
                TextToSpeech.OnInitListener {})
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    fun speakToMe(view: View) {
        alertDialogBuilder.setMessage("I'm speaking!")
        alertDialogBuilder.show()
        val charSeq = "Well hello there!" as CharSequence
        textToSpeech.speak(charSeq, TextToSpeech.QUEUE_FLUSH, null, "")
        while (!textToSpeech.isSpeaking){
            // alertDialogBuilder.dismiss() or some other fun I can't seem to find
        }
    }
}

您需要像这样向您的 tts 添加进度侦听器:

    val params = Bundle()
    params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text)
    tts.setOnUtteranceProgressListener(object : UtteranceProgressListener(){
        override fun onDone(p0: String?) {
         
            //dismiss the AlertDialog here (has to run on UI Thread)

        }
        override fun onError(p0: String?) {
        }
        override fun onStart(p0: String?) {

            //show the AlertDialog here (has to run on UI Thread)
        }
    })
    tts.speak(text ,TextToSpeech.QUEUE_FLUSH, params,"UtterID")

请记住,“UtterID”(可以是您想要的任何内容)对于监听器的功能至关重要。

您不能在主线程中以这种方式使用 while,因为它会锁定 UI 并且您可能会遇到 ANR(应用程序未响应崩溃)。

当你开始演讲的时候,给它一个ID,然后添加一个监听器来响应结果 因为监听器可能会在另一个线程上被调用,所以你必须使用runOnUiThread或者协程去回到主线程再次操作你的 UI。

当您调用 dialogBuilder.show() 时,存储返回的 AlertDialog,以便稍后关闭它。

顺便说一句,没有理由将 String 转换为 CharSequence。您可以将它传递给函数,编译器会将其识别为 CharSequence。

    fun speakToMe(view: View) {
        alertDialogBuilder.setMessage("I'm speaking!")
        val dialog = alertDialogBuilder.show()
        val charSeq = "Well hello there!"
        val id = "speechId"
        textToSpeech.speak(charSeq, TextToSpeech.QUEUE_FLUSH, null, id)
        textToSpeech.onUtteranceProgressListener = object: UtteranceProgressListener {
            override fun onDone(utteranceId: String) {
                if (id == utteranceId) { 
                    runOnUiThread { dialog.dismiss() }
                }
            }
        }
    }