Android RecognitionListener: onResults iki kez çağrılıyor


10

Kotlin'de yazılmış RecognitionListener kullanarak bir projem var. Konuşmadan metne işlevi her zaman başarılı olmuştur ve hiçbir zaman sorun yaşamamıştır.

Geçen haftadan bu yana onResult işlevi iki kez çağrılmaya başlandı. Projede herhangi bir değişiklik yapılmadı. Projenin eski versiyonlarını test ettim (aylar öncesinden) ve aynı problemi vardı.

Üç farklı durum vardır:

  1. Küçük metin (1 - 8 kelime) ve SpeechRecognizer otomatik olarak durduruluyor -> onResult () iki kez çağrılıyor;
  2. Büyük metin (9 kelime veya daha fazla) ve SpeechRecognizer otomatik olarak durduruluyor -> Normal davranış (onResult () bir kez çağrılır);
  3. Herhangi bir metin boyutu ve SpeechRecognizer stopListening () işlevi manuel olarak adlandırılır (koddan) -> Normal davranış.

VoiceRecognition konuşma-metin sınıfı kodu:

class VoiceRecognition(private val activity: Activity, language: String = "pt_BR") : RecognitionListener {

    private val AudioLogTag = "AudioInput"

    var voiceRecognitionIntentHandler: VoiceRecognitionIntentHandler? = null
    var voiceRecognitionOnResultListener: VoiceRecognitionOnResultListener? = null //Must have this
    var voiceRecognitionLayoutChanger: VoiceRecognitionLayoutChanger? = null

    var isListening = false

    private val intent: Intent
    private var speech: SpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(activity)

    init {
        speech.setRecognitionListener(this)

        intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
        intent.putExtra(
            RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
        )
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language)
    }

    //It is important to put this function inside a clickListener
    fun listen(): Boolean {
        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.RECORD_AUDIO), 1)
            return false
        }

        speech.startListening(intent)

        Log.i(AudioLogTag, "startListening")

        return true
    }

    //Use this if you want to stop listening but still get recognition results
    fun endListening(){
        Log.i(AudioLogTag, "stopListening")

        speech.stopListening()
        isListening = false
    }

    fun cancelListening(){
        Log.i(AudioLogTag, "cancelListening")

        speech.cancel()
        voiceRecognitionLayoutChanger?.endListeningChangeLayout()
        isListening = false
    }

    override fun onReadyForSpeech(p0: Bundle?) {
        Log.i(AudioLogTag, "onReadyForSpeech")

        voiceRecognitionLayoutChanger?.startListeningChangeLayout()
        isListening = true
    }

    override fun onRmsChanged(p0: Float) {
//        Log.i(AudioLogTag, "onRmsChanged: $p0")
//        progressBar.setProgress((Int) p0)
    }

    override fun onBufferReceived(p0: ByteArray?) {
        Log.i(AudioLogTag, "onBufferReceived: $p0")
    }

    override fun onPartialResults(p0: Bundle?) {
        Log.i(AudioLogTag, "onPartialResults")
    }

    override fun onEvent(p0: Int, p1: Bundle?) {
        Log.i(AudioLogTag, "onEvent")
    }

    override fun onBeginningOfSpeech() {
        Log.i(AudioLogTag, "onBeginningOfSpeech")
    }

    override fun onEndOfSpeech() {
        Log.i(AudioLogTag, "onEndOfSpeech")

        voiceRecognitionLayoutChanger?.endListeningChangeLayout()
        isListening = false
    }

    override fun onError(p0: Int) {
        speech.cancel()
        val errorMessage = getErrorText(p0)
        Log.d(AudioLogTag, "FAILED: $errorMessage")
        voiceRecognitionLayoutChanger?.endListeningChangeLayout()
        isListening = false
    }

    override fun onResults(p0: Bundle?) {

        val results: ArrayList<String> = p0?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION) as ArrayList<String>

        Log.i(AudioLogTag, "onResults -> ${results.size}")

        val voiceIntent: Int? = voiceRecognitionIntentHandler?.getIntent(results[0])
        if (voiceIntent != null && voiceIntent != 0) {
            voiceRecognitionIntentHandler?.handle(voiceIntent)
            return
        }

        voiceRecognitionOnResultListener!!.onResult(results[0])
    }

    private fun getErrorText(errorCode: Int): String {
        val message: String
        when (errorCode) {
            SpeechRecognizer.ERROR_AUDIO -> message = "Audio recording error"
            SpeechRecognizer.ERROR_CLIENT -> message = "Client side error"
            SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> message = "Insufficient permissions"
            SpeechRecognizer.ERROR_NETWORK -> message = "Network error"
            SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> message = "Network timeout"
            SpeechRecognizer.ERROR_NO_MATCH -> message = "No match"
            SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> message = "RecognitionService busy"
            SpeechRecognizer.ERROR_SERVER -> message = "Error from server"
            SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> message = "No speech input"
            else -> message = "Didn't understand, please try again."
        }
        return message
    }

    //Use it in your overriden onPause function.
    fun onPause() {
        voiceRecognitionLayoutChanger?.endListeningChangeLayout()
        isListening = false

        speech.cancel()
        Log.i(AudioLogTag, "pause")
    }

    //Use it in your overriden onDestroy function.
    fun onDestroy() {
        speech.destroy()
    }

listen (), endListening () ve cancelListening () öğelerinin tümü bir düğmeden çağrılır.


Aynı sorunu yaşıyorum, sorun sadece api 9 ile Samsung s8'de - burada tanıma devam ederken kısmi sonuçlar da görebilirsiniz. Eski cihazlarda bunu yaşamıyorum.
marcinj

Bu problemi Android 7 ve üzeri sürümlerden gördüm ... Projemi bile değiştirmedim .. daha yeni başladı.
Pedro Henrique Flores

"sorun sadece api 9 ile Samsung s8" - bu yüzden sahip olduğum cihazlarda testlerimde demek
marcinj

1
Onlar eğer sonuç, sonra ikinci sonuç aynı görmezden eğer aynı sorun Pocophone F1, benim çözüm kontrol etmek oldu
Lotan

Bu, uygulamalarımdan birinde dün olmaya başladı. Kodun yalnızca bir kez yürütülmesine izin vermek için bir boole ekledim, ancak neden aniden bunu yapmaya başladığına dair bir açıklama isterim. Güncelleme var mı?
Gavin Wright

Yanıtlar:



1

Bu, uygulamalarımdan birinde dün olmaya başladı. Kodun yalnızca bir kez yürütülmesine izin vermek için bir boole ekledim, ancak neden aniden bunu yapmaya başladığına dair bir açıklama isterim. Güncelleme var mı?


0

Aynı sorunu yaşadım ve koduma bir boole bayrağı ekledim, ancak bu geçici bir çözüm ve bu sorunun kaynağını bilmiyorum.

object : RecognitionListener {

        var singleResult = true

        override fun onResults(results: Bundle?) {
            if (singleResult) {
                results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION).let {
                    // do something with result
                }
                // next result will be ignored
                singleResult = false
            }
        }
    }

Lütfen bir örnek kod ekleyin.
m02ph3u5
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.