安卓语音识别API在安卓7.0版本中无法使用

12

我正在使用android.speech.SpeechRecognizer API实现语音识别。

在Android 4-5中它表现得非常好,

但是在Android 6中,它出现了一堆问题,比如当麦克风开启时发出的提示音被识别为语音,因此造成了无限循环(当重新启动时未检测到语音),我们通过一个hack解决了这个问题,即在播放提示音之前将音量设置为0...

在Android 6中,语音识别在5秒后会突然停止,没有任何错误信息。我们也有另一个hack解决方案,即检测5秒内没有活动就重新启动语音识别...

现在,在Android 7中,语音识别似乎根本不起作用? 我还没有找到解决方法,但是否有人遇到了在Android 7中使用语音API的问题?

此外,如果有人知道为什么每个版本的Android都会增加语音API的新缺陷而不是修复它们,请回复。 这种情况是否应该得到Android支持,或者他们希望您使用Google intent代替?


1
你在使用什么设备?许多Nugat设备即使声称支持64位应用程序,但实际上并不支持。尝试使用32位构建它。我曾经遇到类似的问题,并通过这种方式解决了它。 - Andreas Constantinou
1
API在近2年内没有改变(参见https://android.googlesource.com/platform/frameworks/base/+log/refs/heads/master/core/java/android/speech)。您描述了此API的一个实现中的问题,但您未提及是哪个实现(名称、版本号等)。Android本身不包含语音识别器的实现,尽管许多手机都预装了Google的实现。 - Kaarel
1
三星 G7 使用 Android 7,语音功能无法正常工作。 - James
1
其他错误发生在三星G6上,使用Android 6,以及我们测试过的各种其他手机型号上,通常较旧的手机效果更好,而较新的则不太行。 - James
1
你确定已经安装了语音识别服务提供程序吗?SpeechRecognizer.isRecognitionAvailable(mContext)。你确认在三星设备上没有将提供程序设置为Vlingo吗?虽然代码会告诉你它可以工作,但实际上并不行。Google的实现每次发布都变得更糟。如果你想自己处理所有事情,我建议切换到他们的Cloud Speech API。 - brandall
显示剩余4条评论
1个回答

4

我的代码在Nexus5x(Nougat)和Nexus9(Nougat)上运行良好。

尝试并显示logcat日志。

SpeechRecognizer mGoogleSr;

void initGoogleSr(Context context) {
    mGoogleSr = SpeechRecognizer.createSpeechRecognizer(context);
    mGoogleSr.setRecognitionListener(new GoogleSrListener());
}

void startGoogleSr() {
    if (mGoogleSr != null) {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
        mGoogleSr.startListening(intent);
    }
}
void cancelRecognizing() {
    if (mGoogleSr != null) {
        mGoogleSr.cancel();
    }
}

public class GoogleSrListener implements RecognitionListener {
    String lastPartialText;

    @Override
    public void onReadyForSpeech(Bundle params) {
        Log.v(TAG, ">>> onReadyForSpeech");
        showMessage("ready");
    }

    @Override
    public void onBeginningOfSpeech() {
        Log.v(TAG, ">>> onBeginningOfSpeech");
        showMessage("recognizing");
    }

    @Override
    public void onRmsChanged(float rmsdB) {
    }

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

    }

    @Override
    public void onEndOfSpeech() {
        Log.v(TAG, ">>> onEndOfSpeech");
        showMessage("waiting result");
    }

    @Override
    public void onError(int error) {
        Log.v(TAG, ">>> onError : " + error);
        switch (error) {
            case SpeechRecognizer.ERROR_AUDIO:
                Log.e(TAG, "ERROR_AUDIO");
                break;
            case SpeechRecognizer.ERROR_CLIENT:
                Log.e(TAG, "ERROR_CLIENT");
                break;
            case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                Log.e(TAG, "ERROR_INSUFFICIENT_PERMISSIONS");
                break;
            case SpeechRecognizer.ERROR_NETWORK:
                Log.e(TAG, "ERROR_NETWORK");
                break;
            case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                Log.e(TAG, "ERROR_NETWORK_TIMEOUT");
                break;
            case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                Log.e(TAG, "ERROR_RECOGNIZER_BUSY");
                break;
            case SpeechRecognizer.ERROR_SERVER:
                Log.e(TAG, "ERROR_SERVER");
                break;
            case SpeechRecognizer.ERROR_NO_MATCH:
                Log.v(TAG, "ERROR_NO_MATCH");
                break;
            case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                Log.v(TAG, "ERROR_SPEECH_TIMEOUT");
                break;
            default:
                Log.v(TAG, "ERROR_UNKOWN");
        }
    }

    @Override
    public void onPartialResults(Bundle partialResults) {
        Log.v(TAG, ">>> onPartialResults");
        List<String> resultList = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        if (resultList != null) {
            String text = resultList.get(0);
            if (text.equals(lastPartialText)) {
                return;
            }
            lastPartialText = text;
            Log.v(TAG, "partial : " + text);
        }
    }

    @Override
    public void onResults(Bundle results) {
        Log.v(TAG, ">>> onResults");
        List<String> resultList = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        if (resultList != null) {
            String text = resultList.get(0);
            Log.v(TAG, "result : " + text);
            showMessage(text);
        }
    }

    @Override
    public void onEvent(int eventType, Bundle params) {
        Log.v(TAG, ">>> onEvent type = " + eventType);
    }
}

清单文件中的权限(可能会有冗余):

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接