【问题标题】:Why does Android speech recogniser crash after new update? Do I need to make changes to my code?为什么Android语音识别器在新更新后会崩溃?我需要更改我的代码吗?
【发布时间】:2018-07-17 15:18:17
【问题描述】:

我一直在探索 Android Studio 的语音识别领域。这是我第一次使用 TextToSpeech 和 SpeechRecognizer 开发应用程序。每当我点击语音按钮时,应用程序就会崩溃。请注意,我是初学者,对 Java 没有完全掌握。

    package com.blindnavi.navirecog;

import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.format.DateUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import java.util.Date;
import java.util.List;
import java.util.Locale;

public class NaviCaroline extends AppCompatActivity {

private TextToSpeech NaviVoice;
private SpeechRecognizer NaviSay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_navi_caroline);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
            intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
            NaviSay.startListening(intent);
        }
    });

    initializeTextToSpeech();
    initializeSpeechRecognizer();
}

private void initializeSpeechRecognizer() {
    if(SpeechRecognizer.isRecognitionAvailable(this)) {
        NaviSay = SpeechRecognizer.createSpeechRecognizer(this);
        NaviSay.setRecognitionListener((new RecognitionListener() {
            @Override
            public void onReadyForSpeech(Bundle params) {

            }

            @Override
            public void onBeginningOfSpeech() {

            }

            @Override
            public void onRmsChanged(float rmsdB) {

            }

            @Override
            public void onBufferReceived(byte[] buffer) {

            }

            @Override
            public void onEndOfSpeech() {

            }

            @Override
            public void onError(int error) {

            }

            @Override
            public void onResults(Bundle bundle) {
                List<String> results = bundle.getStringArrayList(
                        SpeechRecognizer.RESULTS_RECOGNITION
                );
                processResult(results.get(0));
            }

            @Override
            public void onPartialResults(Bundle partialResults) {

            }

            @Override
            public void onEvent(int eventType, Bundle params) {

            }
        }));
    }
}

private void processResult(String command) {
    command = command.toLowerCase();

    //what is your name
    //what is the time
    //open a browser

    if(command.indexOf("what") != -1) {
        if (command.indexOf("your name") != -1) {
            speak("My name is Caroline.");
        }
        if (command.indexOf("time") != -1) {
            Date now = new Date();
            String time = DateUtils.formatDateTime(this, now.getTime(),
                    DateUtils.FORMAT_SHOW_TIME);
            speak("The time now is " + time);
        }
    } else if(command.indexOf("open") != -1) {
        if(command.indexOf("browser") != -1) {
            Intent intent = new Intent(Intent.ACTION_VIEW,
                    Uri.parse("https:/tutsplus.com"));
            startActivity(intent);
        }
    }
}

private void initializeTextToSpeech() {
    NaviVoice = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if(NaviVoice.getEngines().size() == 0) {
                Toast.makeText(NaviCaroline.this, "There is no TextToSpeech engine on your device.",
                        Toast.LENGTH_LONG);
                finish();
            } else {
                NaviVoice.setLanguage(Locale.UK);
                speak("Welcome to BlindNavi.");
            }
        }
    });
}

private void speak(String message) {
    if(Build.VERSION.SDK_INT >= 21) {
        NaviVoice.speak(message, TextToSpeech.QUEUE_FLUSH, null, null);
    } else {
        NaviVoice.speak(message, TextToSpeech.QUEUE_FLUSH, null);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_navi_caroline, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
protected void onPause() {
    super.onPause();
    NaviVoice.shutdown();
}
}

请原谅我添加了这么多代码,但我在任何地方都找不到问题。

非常感谢您的帮助。

附言 “record_audio”权限已创建。

堆栈跟踪:

07-17 16:05:22.062 16743-16743/com.blindnavi.navirecog E/BoostFramework: BoostFramework() : Exception_1 = java.lang.ClassNotFoundException: 找不到类“com.qualcomm.qti.Performance”在路径上:DexPathList[[],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]] 07-17 16:05:22.062 16743-16743/com.blindnavi.navirecog V/BoostFramework: BoostFramework() : mPerf = null 07-17 16:05:22.120 16743-16743/com.blindnavi.navirecog D/ViewRootImpl@e5200a4[NaviCaroline]:ViewPostImeInputStage 进程指针 1 07-17 16:05:22.137 16743-16743/com.blindnavi.navirecog D/AndroidRuntime: 关闭虚拟机 07-17 16:05:22.138 16743-16743/com.blindnavi.navirecog E/AndroidRuntime: 致命异常: main 进程:com.blindnavi.navirecog,PID:16743 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.speech.SpeechRecognizer.startListening(android.content.Intent)” 在 com.blindnavi.navirecog.NaviCaroline$1.onClick(NaviCaroline.java:45) 在 android.view.View.performClick(View.java:6205) 在 android.view.View$PerformClick.run(View.java:23653) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6682) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

【问题讨论】:

  • 请同时发布堆栈跟踪
  • 如果SpeechRecognizer.isRecognitionAvailable(this)返回false,应用程序也会崩溃,因为naviSay在这种情况下为空

标签: android android-studio speech-recognition text-to-speech


【解决方案1】:

你应该这样写你的代码,

if(!SpeechRecognizer.isRecognitionAvailable(this)) {
    Toast.makeText(NaviCaroline.this, "SpeechToText is unavailable.", Toast.LENGTH_LONG);
    finish();
}
else{
    NaviSay = SpeechRecognizer.createSpeechRecognizer(this);
    //initialize stt

我不知道为什么 isRecognitionAvailable 返回 false,但是您应该在 android 6.0 或更高版本上调用 isRecognitionAvailable() 之前检查您请求的所有权限。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多