背景:语音拍照功能的实现 不让用三方算法库
所以只能选择android 原生speechRecognizer
其实就是解决语音转文字 文字转好了逻辑就很好处理
speechRecognizer的用法
SpeechRecognizer 位于 android.speech package 中
源码:/frameworks/base/core/java/android/speech/SpeechRecognizer.java
即
import android.speech.SpeechRecognizer;
谷歌Android SpeechRecognizer的Docs位置:
https://developer.android.com/reference/android/speech/SpeechRecognizer.html
1.第一步,首先权限申请 android 6.0 之后都要动态申请权限
在androidManifest 中添加网络 以及音频权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
2.第二步,实例化一个speechRecognizer对象
利用SpeechRecognizer的createSpeechRecognizer方法该方法需要传递一个Context
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(MainActivity.this);
3.第三步,设置识别监听
speechRecognizer.setRecognitionListener((android.speech.RecognitionListener) new SampleRecognitionListener());
4.第四步,利用RecognitionListener实现监听逻辑
class SampleRecognitionListener implements RecognitionListener {
@Override
public void onReadyForSpeech(Bundle bundle) {
Log.d(TAG, "onReadyForSpeech Start");
Log.d(TAG, "onReadyForSpeech End");
}
@Override
public void onBeginningOfSpeech() {
Log.d(TAG, "onBeginningOfSpeech Start");
Log.d(TAG, "onBeginningOfSpeech End");
}
@Override
public void onRmsChanged(float v) {
Log.d(TAG, "onRmsChanged Start");
Log.d(TAG, "onRmsChanged End");
}
@Override
public void onBufferReceived(byte[] bytes) {
Log.d(TAG, "onBufferReceived Start");
Log.d(TAG, "onBufferReceived End");
}
@Override
public void onEndOfSpeech() {
Log.d(TAG, "onEndOfSpeech Start");
Log.d(TAG, "onEndOfSpeech End");
}
@Override
public void onError(int error) {
Log.d(TAG, "onError Start");
switch (error) {
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
resetText("网络链接超时");
break;
case SpeechRecognizer.ERROR_NETWORK:
resetText("网络错误或者没有权限");
break;
case SpeechRecognizer.ERROR_AUDIO:
resetText("音频发生错误");
break;
case SpeechRecognizer.ERROR_CLIENT:
resetText("连接出错");
break;
case SpeechRecognizer.ERROR_SERVER:
resetText("服务器出错");
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
resetText("什么也没有听到");
break;
case SpeechRecognizer.ERROR_NO_MATCH:
resetText("没有匹配到合适的结果");
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
resetText("RecognitionService已经启动,请稍后");
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
resetText("请赋予APP权限,另请(Android6.0以上)确认动态申请权限");
break;
default:
break;
}
Log.d(TAG, "onError End");
}
@Override
public void onResults(Bundle results) {
Log.d(TAG, "onResults Start");
String key = SpeechRecognizer.RESULTS_RECOGNITION;
ArrayList mResult = results.getStringArrayList(key);
String[] result = new String[0];
if (mResult != null) {
result = new String[mResult.size()];
}
if (mResult != null) {
mResult.toArray(result);
}
Log.d(TAG, "Recognize Result:" + result);
resetText(result[0]);
Log.d(TAG, "onResults End");
}
@Override
public void onPartialResults(Bundle bundle) {
Log.d(TAG, "onPartialResults Start");
Log.d(TAG, "onPartialResults End");
}
@Override
public void onEvent(int i, Bundle bundle) {
Log.d(TAG, "onEvent Start");
Log.d(TAG, "onEvent End");
}
}
第五步,开启监听服务
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.CHINESE.toString());
speechRecognizer.startListening(intent);
在onResults回调里面就可以拿到 识别结果
完整demo如下
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp">
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="~Start~" />
<Button
android:id="@+id/end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="~End~" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"></LinearLayout>
<TextView
android:id="@+id/editText"
android:textSize="30sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="请点击start然后下发指令"/>
</LinearLayout>
MainActivity.java
package com.example.myspeech;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private String TAG = "SpeechRecognizer";
private SpeechRecognizer speechRecognizer;
final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
//
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(MainActivity.this);
speechRecognizer.setRecognitionListener((android.speech.RecognitionListener) new SampleRecognitionListener());
Log.d(TAG, "Start Recognize");
Log.d(TAG, "Recognize is available:" + speechRecognizer.isRecognitionAvailable(MainActivity.this));
Button button1 = findViewById(R.id.start);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(speechRecognizer == null) {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(MainActivity.this);
speechRecognizer.setRecognitionListener((android.speech.RecognitionListener) new SampleRecognitionListener());
}
//requestPermission();
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.CHINESE.toString());
speechRecognizer.startListening(intent);
}
});
Button button2 = findViewById(R.id.end);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//SpeechRecognizer 会自动检测到说话结束,但是用该方法可以手动停止Recognizer
speechRecognizer.stopListening();
speechRecognizer.cancel();
speechRecognizer.destroy();
}
});
}
@Override
protected void onStop() {
super.onStop();
speechRecognizer.cancel();
speechRecognizer.destroy();
}
class SampleRecognitionListener implements RecognitionListener {
@Override
public void onReadyForSpeech(Bundle bundle) {
Log.d(TAG, "onReadyForSpeech Start");
Log.d(TAG, "onReadyForSpeech End");
}
@Override
public void onBeginningOfSpeech() {
Log.d(TAG, "onBeginningOfSpeech Start");
Log.d(TAG, "onBeginningOfSpeech End");
}
@Override
public void onRmsChanged(float v) {
Log.d(TAG, "onRmsChanged Start");
Log.d(TAG, "onRmsChanged End");
}
@Override
public void onBufferReceived(byte[] bytes) {
Log.d(TAG, "onBufferReceived Start");
Log.d(TAG, "onBufferReceived End");
}
@Override
public void onEndOfSpeech() {
Log.d(TAG, "onEndOfSpeech Start");
Log.d(TAG, "onEndOfSpeech End");
}
@Override
public void onError(int error) {
Log.d(TAG, "onError Start");
switch (error) {
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
resetText("网络链接超时");
break;
case SpeechRecognizer.ERROR_NETWORK:
resetText("网络错误或者没有权限");
break;
case SpeechRecognizer.ERROR_AUDIO:
resetText("音频发生错误");
break;
case SpeechRecognizer.ERROR_CLIENT:
resetText("连接出错");
break;
case SpeechRecognizer.ERROR_SERVER:
resetText("服务器出错");
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
resetText("什么也没有听到");
break;
case SpeechRecognizer.ERROR_NO_MATCH:
resetText("没有匹配到合适的结果");
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
resetText("RecognitionService已经启动,请稍后");
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
resetText("请赋予APP权限,另请(Android6.0以上)确认动态申请权限");
break;
default:
break;
}
Log.d(TAG, "onError End");
}
@Override
public void onResults(Bundle results) {
Log.d(TAG, "onResults Start");
String key = SpeechRecognizer.RESULTS_RECOGNITION;
ArrayList mResult = results.getStringArrayList(key);
String[] result = new String[0];
if (mResult != null) {
result = new String[mResult.size()];
}
if (mResult != null) {
mResult.toArray(result);
}
Log.d(TAG, "Recognize Result:" + result);
resetText(result[0]);
Log.d(TAG, "onResults End");
}
@Override
public void onPartialResults(Bundle bundle) {
Log.d(TAG, "onPartialResults Start");
Log.d(TAG, "onPartialResults End");
}
@Override
public void onEvent(int i, Bundle bundle) {
Log.d(TAG, "onEvent Start");
Log.d(TAG, "onEvent End");
}
}
//给EditText 设置 Text
private void resetText(String text) {
TextView result = findViewById(R.id.editText);
result.setText(text);
}
//记得6.0以后动态请求权限,不然会一直提示网络错误
private void requestPermission() {
Log.d(TAG, "requestPermission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.INTERNET}, MY_PERMISSIONS_REQUEST_RECORD_AUDIO);
}
}
就可以实现简单的原生语音识别功能
成果展示:点了start并说了拍照