关于语音识别的 Android 额外功能不起作用

标签 android speech-recognition speech-to-text

我目前正忙于语音识别,我希望语音识别器能够持续不断地倾听我的声音。该应用程序的目的是等待特定关键字的语音:当用户说出此关键字时,该服务准备好接收用户语音命令经过研究我发现我们可以操纵识别器收听的时间。通过这些常量:

顺便说一句,默认的识别器服务会监听大约 10 秒。 (谷歌 API)

     String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS   The amount of time that it should take after we stop hearing speech to consider the input complete.
     String EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS    The minimum length of an utterance.
     String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS  The amount of time that it should take after we stop hearing speech to consider the input possibly complete.

http://java.llp2.dcc.ufmg.br/apiminer/docs/reference/android/speech/RecognizerIntent.html

这些是 bundle 类的额外内容。

问题是,当我在我的代码中使用这些常量时,它不起作用。

这是我的代码:

   intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 5000);
   intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);
   intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);

虽然我写了 5000 毫秒,但识别器仍会听我大约 10 秒,如您所见。

你能想到这个问题吗?也许我不知道如何使用附加功能,或者可能与权限有关,也许它会跳过我的代码,或者我应该添加一些其他代码。

如有任何帮助,我们将不胜感激。

编辑:这是我的完整代码:

VoiceRecognitionActivity.java

public class VoiceRecognitionActivity extends Activity implements
    TextToSpeech.OnInitListener {

private static final int REQUEST_CODE = 1234;
private Button mTalkButton;
private ListView wordsList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_voice_recognition);
    mTalkButton = (Button) findViewById(R.id.talk_button);
    wordsList = (ListView) findViewById(R.id.listView1);
    // Disable button if no recognition service is present
    PackageManager pm = getPackageManager();
    List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
            RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
    if (activities.size() == 0) {
        mTalkButton.setEnabled(false);
        mTalkButton.setText("Recognizer not present");
    } else {
        mTalkButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                        RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
                        "Voice recognition Demo...");
                String defaultLanguage = Locale
                        .getDefault().toString();
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale
                        .getDefault());

                intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 5000);
                intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);
                intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);

                startActivityForResult(intent, REQUEST_CODE);

            }
        });
    }
}

/**
 * Handle the results from the voice recognition activity.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        // Populate the wordsList with the String values the recognition
        // engine thought it heard
        ArrayList<String> matches = data
                .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        wordsList.setAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, matches));
    }
    super.onActivityResult(requestCode, resultCode, data);
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.menu_settings:
        startActivity(new Intent(this, SettingsActivity.class));
        return true;

    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public void onInit(int status) {
    // TODO Auto-generated method stub

}

TTSUtils.java

公共(public)类 TTSUtils 实现 TextToSpeech.OnInitListener {

private TextToSpeech mTts;
private static TTSUtils mInstance;
private Context mContext;

public static TTSUtils getInstance(Context c) {
    if (mInstance == null) {
        mInstance = new TTSUtils(c);
    }
    return mInstance;
}

private TTSUtils(Context c) {
    mContext = c;
    mTts = new TextToSpeech(mContext, this);
    mInstance = this;
}

@Override
public void onInit(int status) {
    // TODO Auto-generated method stub

}

public void destroyTTS() {
    if (mTts != null) {
        mTts.stop();
        mTts.shutdown();
    }
}

public int setLanguage(Locale l) {
    return mTts.setLanguage(l);
}

public int speak(String s, int i, HashMap<String, String> h) {
    return mTts.speak(s, i, h);
}

SettingsActivity.java

公共(public)类 SettingsActivity 扩展 PreferenceActivity {

/**
 * Determines whether to always show the simplified settings UI, where
 * settings are presented in a single list. When false, settings are shown
 * as a master/detail two-pane view on tablets. When true, a single pane is
 * shown on tablets.
 */

private static final boolean ALWAYS_SIMPLE_PREFS = false;

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);

    setupSimplePreferencesScreen();
}

/**
 * Shows the simplified settings UI if the device configuration if the
 * device configuration dictates that a simplified, single-pane UI should be
 * shown.
 */
private void setupSimplePreferencesScreen() {
    if (!isSimplePreferences(this)) {
        return;
    }

    // In the simplified UI, fragments are not used at all and we instead
    // use the older PreferenceActivity APIs.

    // Add 'general' preferences.
    addPreferencesFromResource(R.xml.pref_general);

    // Add 'notifications' preferences, and a corresponding header.
    PreferenceCategory fakeHeader = new PreferenceCategory(this);
    fakeHeader.setTitle(R.string.pref_header_notifications);
    getPreferenceScreen().addPreference(fakeHeader);
    addPreferencesFromResource(R.xml.pref_notification);

    // Add 'data and sync' preferences, and a corresponding header.
    fakeHeader = new PreferenceCategory(this);
    fakeHeader.setTitle(R.string.pref_header_data_sync);
    getPreferenceScreen().addPreference(fakeHeader);
    addPreferencesFromResource(R.xml.pref_data_sync);

    // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
    // their values. When their values change, their summaries are updated
    // to reflect the new value, per the Android Design guidelines.
    bindPreferenceSummaryToValue(findPreference("example_text"));
    bindPreferenceSummaryToValue(findPreference("example_list"));
    bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
    bindPreferenceSummaryToValue(findPreference("sync_frequency"));
}

/** {@inheritDoc} */
@Override
public boolean onIsMultiPane() {
    return isXLargeTablet(this) && !isSimplePreferences(this);
}

/**
 * Helper method to determine if the device has an extra-large screen. For
 * example, 10" tablets are extra-large.
 */
private static boolean isXLargeTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}

/**
 * Determines whether the simplified settings UI should be shown. This is
 * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device
 * doesn't have newer APIs like {@link PreferenceFragment}, or the device
 * doesn't have an extra-large screen. In these cases, a single-pane
 * "simplified" settings UI should be shown.
 */
private static boolean isSimplePreferences(Context context) {
    return ALWAYS_SIMPLE_PREFS
            || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
            || !isXLargeTablet(context);
}

/** {@inheritDoc} */
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
    if (!isSimplePreferences(this)) {
        loadHeadersFromResource(R.xml.pref_headers, target);
    }
}

/**
 * A preference value change listener that updates the preference's summary
 * to reflect its new value.
 */
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list.
            ListPreference listPreference = (ListPreference) preference;
            int index = listPreference.findIndexOfValue(stringValue);

            // Set the summary to reflect the new value.
            preference
                    .setSummary(index >= 0 ? listPreference.getEntries()[index]
                            : null);

        } else if (preference instanceof RingtonePreference) {
            // For ringtone preferences, look up the correct display value
            // using RingtoneManager.
            if (TextUtils.isEmpty(stringValue)) {
                // Empty values correspond to 'silent' (no ringtone).
                preference.setSummary(R.string.pref_ringtone_silent);

            } else {
                Ringtone ringtone = RingtoneManager.getRingtone(
                        preference.getContext(), Uri.parse(stringValue));

                if (ringtone == null) {
                    // Clear the summary if there was a lookup error.
                    preference.setSummary(null);
                } else {
                    // Set the summary to reflect the new ringtone display
                    // name.
                    String name = ringtone
                            .getTitle(preference.getContext());
                    preference.setSummary(name);
                }
            }

        } else {
            // For all other preferences, set the summary to the value's
            // simple string representation.
            preference.setSummary(stringValue);
        }
        return true;
    }
};

/**
 * Binds a preference's summary to its value. More specifically, when the
 * preference's value is changed, its summary (line of text below the
 * preference title) is updated to reflect the value. The summary is also
 * immediately updated upon calling this method. The exact display format is
 * dependent on the type of preference.
 * 
 * @see #sBindPreferenceSummaryToValueListener
 */
private static void bindPreferenceSummaryToValue(Preference preference) {
    // Set the listener to watch for value changes.
    preference
            .setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

    // Trigger the listener immediately with the preference's
    // current value.
    sBindPreferenceSummaryToValueListener.onPreferenceChange(
            preference,
            PreferenceManager.getDefaultSharedPreferences(
                    preference.getContext()).getString(preference.getKey(),
                    ""));
}

/**
 * This fragment shows general preferences only. It is used when the
 * activity is showing a two-pane settings UI.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_general);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences
        // to their values. When their values change, their summaries are
        // updated to reflect the new value, per the Android Design
        // guidelines.
        bindPreferenceSummaryToValue(findPreference("example_text"));
        bindPreferenceSummaryToValue(findPreference("example_list"));
    }
}

/**
 * This fragment shows notification preferences only. It is used when the
 * activity is showing a two-pane settings UI.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class NotificationPreferenceFragment extends
        PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_notification);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences
        // to their values. When their values change, their summaries are
        // updated to reflect the new value, per the Android Design
        // guidelines.
        bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
    }
}

/**
 * This fragment shows data and sync preferences only. It is used when the
 * activity is showing a two-pane settings UI.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class DataSyncPreferenceFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_data_sync);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences
        // to their values. When their values change, their summaries are
        // updated to reflect the new value, per the Android Design
        // guidelines.
        bindPreferenceSummaryToValue(findPreference("sync_frequency"));
    }
}

最佳答案

在最近的 Google 搜索更新中,这些参数不再适用于 Jelly Bean 设备。一段时间以来,我一直想提交一份关于 if 的错误报告。它们仍然适用于 ICS 及以下设备。

如果您想在不超时的情况下继续监听关键字,则必须执行循环,从而检查 onPartialResults 中的关键字。 .如果Results被调用,也没有检测到关键字,需要立即重新开始识别。

您需要处理 silent death bug并将系统音频流静音为 prevent the Jelly Bean beep sound .

这些问题使实现变得非常困惑和令人沮丧。谷歌整理....

关于关于语音识别的 Android 额外功能不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15660805/

相关文章:

c# - System.Speech.Recognition 选择识别配置文件

java - 我可以从语音识别中获取语音数据(例如 mp3 格式)吗?

android - Android 应用程序是否可以结束它发起的调用?

java - imageview源码在java文件和xml文件中?

nlp - Dialogflow 无法识别训练短语中的名称

c# - Windows Phone 8 中的语音识别

android - Google Speech to Text 对话框卡住了

android - nme haxe,无法使用 flashdevelop 在 android 平台上构建

Android:定位debug.keystore时命令行出现keytool错误

c# - 在不使用 Windows 语音识别的情况下,C# 中的语音识别