这几天两个舍友都买了iPhone 6S,玩起了“Hey, Siri”,我依旧对我的Nexus 5喊着“OK,Google”。但种种原因,国内的“OK,Google”并不能展示出他的全部威力,于是上网搜索国内Android平台的语音助手,个人觉得评价最好的是讯飞的——灵犀语音助手。其实讯飞语音云平台早就注册过了,并下载了相应的SDK,只是没仔细研究。今天突然想好好学习一下,以方便以后集成到自己开发的APP中,也可以方便大家参考。开发工具:Android Studio。
好了,废话就说这些。先来看效果图:
下面是具体的步骤。
1,首先在讯飞开放平台注册开发者账号,注册流程很简单,就不详细介绍。网址:http://www.xfyun.cn/。然后就是像各大平台一样的步骤:新建Android应用获取APPID—〉下载语音听写SDK。此处需要注意的是一定要新建自己的应用,别人的工程虽然能用,但不方便后续开发。
2,解压下载的SDK目录,里面有详细的教程,可自行参考。然后新建工程,将MSC.jar(放入到libs文件夹下)和libmsc.so(放入到新建的jniLibs文件夹下)导入到自己的工程中(只有在线的所有功能,没有提供离线服务。)另外,讯飞提供了两种语音识别接口,一种是后台进行语音检测,没有界面UI提示;另一种是带UI的接口,在录音、播放音频的时候,会有dialog弹出,并伴有相应的动画,相对来说用户交互体验很不错。如果使用带UI接口时,请将assets下文件拷贝到项目中。这里注意的是每个SDK下载的assets可能不一样(没有亲自测试过,因为recognize.xml打开乱码),一定要将自己下载的SDK里的assets目录拷贝到XXX/src/main文件夹下。工程目录如下:
3,在AndroidManifest.xml文件中添加权限:
<!-- 在工程 AndroidManifest.xml 文件中添加如下权限 -->
<!-- 连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- 外存储写入权限, 构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
4,布局文件activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<EditText
android:id="@+id/content_rec"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="识别内容" />
<Button
android:id="@+id/bt_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="startRec"
android:text="开始" />
<Button
android:id="@+id/btn_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/bt_start"
android:layout_alignLeft="@+id/bt_start"
android:layout_alignParentRight="true"
android:onClick="read"
android:text="朗读" />
</RelativeLayout>
5,Java代码:JsonParser.java 和 MainActivity.java
(1),JsonParser.Java
package com.xiaobailong24.xunfeiyun;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
* Json结果解析类
*/
public class JsonParser {
public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
// 如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseLocalGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
}
(2),MainActivity.java
package com.xiaobailong24.xunfeiyun;
import android.app.Activity;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
public class MainActivity extends Activity {
private static String TAG = "MainActivity";
// 函数调用返回值
int ret = 0;
// 语音听写对象
private SpeechRecognizer mIat;
// 语音听写UI
private RecognizerDialog iatDialog;
// 听写结果内容
private EditText mResultText;
// 语音合成对象
private SpeechSynthesizer mTts;
// 默认发音人
private String voicer = "xiaoyan";
// 缓冲进度
private int mPercentForBuffering = 0;
// 播放进度
private int mPercentForPlaying = 0;
private Toast mToast;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "onCreate");
super.onCreate(savedInstanceState);
// this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// 用于验证应用的key,将XXXXXXXX改为你申请的APPID
SpeechUtility.createUtility(MainActivity.this, SpeechConstant.APPID + "=XXXXXXXX");
// 创建语音听写对象
mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
// 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
// 创建语音听写UI
iatDialog = new RecognizerDialog(MainActivity.this, mInitListener);
// 创建语音合成对象
mTts = SpeechSynthesizer.createSynthesizer(this, mInitListener);
mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
content_rec));
}
public void startRec(View view) {
mResultText.setText(null);
setParam();
boolean isShowDialog = true;
if (isShowDialog) {
// 显示听写对话框
iatDialog.setListener(recognizerDialogListener);
iatDialog.show();
// showTip("begin");
} else {
// 不显示听写对话框
ret = mIat.startListening(recognizerListener);
if (ret != ErrorCode.SUCCESS) {
// showTip("听写失败,错误码:" + ret);
} else {
// showTip("begin");
}
}
}
public void read(View view) {
String text = mResultText.getText().toString();
// 设置参数
setParam2();
//朗读
int code = mTts.startSpeaking(text, mTtsListener);
if (code != ErrorCode.SUCCESS) {
if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
// 未安装则跳转到提示安装页面
} else {
showTip("语音合成失败,错误码: " + code);
}
}
}
/**
* 参数设置
*
* @param
* @return
*/
private void setParam2() {
Log.e(TAG, "setParam2");
// 设置合成
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
// 设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
// 设置语速
mTts.setParameter(SpeechConstant.SPEED, "50");
// 设置音调
mTts.setParameter(SpeechConstant.PITCH, "50");
// 设置音量
mTts.setParameter(SpeechConstant.VOLUME, "50");
// 设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
}
public void setParam() {
Log.e(TAG, "setParam");
// 清空参数
mIat.setParameter(SpeechConstant.PARAMS, null);
// 设置听写引擎
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 设置语言区域
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
// 设置语音前端点
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
// 设置语音后端点
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
// 设置标点符号 1为有标点 0为没标点
mIat.setParameter(SpeechConstant.ASR_PTT, "0");
// 设置音频保存路径
mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH,
Environment.getExternalStorageDirectory()
+ "/xiaobailong24/xunfeiyun");
}
/**
* 合成回调监听。
*/
private SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
Log.e(TAG, "mTtsListener-->onSpeakBegin");
showTip("开始播放");
}
@Override
public void onSpeakPaused() {
Log.e(TAG, "mTtsListener-->onSpeakPaused");
showTip("暂停播放");
}
@Override
public void onSpeakResumed() {
Log.e(TAG, "mTtsListener-->onSpeakResumed");
showTip("继续播放");
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
Log.e(TAG, "mTtsListener-->onBufferProgress");
mPercentForBuffering = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
Log.e(TAG, "mTtsListener-->onSpeakProgress");
mPercentForPlaying = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onCompleted(SpeechError error) {
Log.e(TAG, "mTtsListener-->onCompleted");
if (error == null) {
showTip("播放完成");
} else if (error != null) {
showTip(error.getPlainDescription(true));
}
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
Log.e(TAG, "mTtsListener-->onEvent");
}
};
/**
* 听写监听器。
*/
private RecognizerListener recognizerListener = new RecognizerListener() {
@Override
public void onVolumeChanged(int i, byte[] bytes) {
Log.e(TAG, "recognizerListener-->onVolumeChanged");
showTip("当前正在说话,音量大小:" + i);
}
@Override
public void onBeginOfSpeech() {
Log.e(TAG, "recognizerListener-->onBeginOfSpeech");
showTip("开始说话");
}
@Override
public void onEndOfSpeech() {
Log.e(TAG, "recognizerListener-->onEndOfSpeech");
showTip("结束说话");
}
@Override
public void onResult(RecognizerResult results, boolean isLast) {
Log.e(TAG, "recognizerListener-->onResult");
String text = JsonParser.parseIatResult(results.getResultString());
mResultText.append(text);
mResultText.setSelection(mResultText.length());
if (isLast) {
// TODO 最后的结果
}
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
Log.e(TAG, "recognizerListener-->onEvent");
}
@Override
public void onError(SpeechError arg0) {
Log.e(TAG, "recognizerListener-->onError");
// TODO Auto-generated method stub
}
};
/**
* 听写UI监听器
*/
private RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult results, boolean isLast) {
Log.e(TAG, "recognizerDialogListener-->onResult");
String text = JsonParser.parseIatResult(results.getResultString());
mResultText.append(text);
mResultText.setSelection(mResultText.length());
}
/**
* 识别回调错误.
*/
public void onError(SpeechError error) {
Log.e(TAG, "recognizerDialogListener-->onError");
showTip(error.getPlainDescription(true));
}
};
private InitListener mInitListener = new InitListener() {
@Override
public void onInit(int code) {
Log.e(TAG, "mInitListener-->onInit");
Log.d(TAG, "SpeechRecognizer init() code = " + code);
if (code != ErrorCode.SUCCESS) {
showTip("初始化失败,错误码:" + code);
}
}
};
private void showTip(final String str) {
Log.e(TAG, "showTip-->" + str);
mToast.setText(str);
mToast.show();
}
@Override
protected void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
// 退出时释放连接
mIat.cancel();
mIat.destroy();
}
@Override
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
}
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
}
}
原文:http://www.cnblogs.com/wxb20/p/6095483.html