概述
开发工具是Android Studio,实现了一个中英互译的安卓app,调用科大讯飞的语音识别、语音合成api以及百度翻译api,需要科大讯飞的appid,以及百度翻译的appid和密钥。
App运行截图:
科大讯飞的语音识别、语音合成api调用流程(SDK调用方式):
科大讯飞开放平台官网:
讯飞开放平台-以语音交互为核心的人工智能开放平台科大讯飞推出的移动互联网智能交互平台,为开发者免费提供:涵盖语音能力增强型SDK,一站式人机智能语音交互解决方案,专业全面的移动应用分析;https://www.xfyun.cn/
1.先注册账号登陆,创建新应用
先去讯飞开发平台注册成为开发者,申请APPID,创建新应用,需要确定应用名称、应用分类、应用功能描述,其中应用分类我选的是应用-教育学习-学习。当新应用创建好后,每天免费服务量是500。
*SDK调用方式只需APPID。APIKey或APISecret适用于WebAPI调用方式。
2.导入SDK
需要在项目main文件夹下新建Jnilibs并拷贝libmsc.so,msc.jar需要拷贝至项目libs下,并且右键jar添加Add As Library,sdk下文件夹main/assets/,自带UI页面(iflytek文件夹)和相关其他服务资源文件(语法文件、音频示例、词表),使用自带UI接口时,可以将assets/iflytek文件拷贝到项目中。
注:arm版本已经逐步淘汰了,arm架构的推荐使用armeabi-v7a。
当你点按钮开始说话时,会出现动画及图标,这些来源就是iflytek文件夹下的。
3.添加用户权限
在工程 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"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄像头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />
4.相关代码
只介绍科大讯飞这部分核心代码
引入依赖
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;
定义变量:
// 用HashMap存储听写结果
private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
private Button bt_zhspeech;
private SpeechSynthesizer mTts;// 语音合成
private SpeechRecognizer mIat;// 语音听写
private Button bt_enwrite;
private RecognizerDialog iatDialog;//听写动画
static String flag;
private String[] voiceName = {"xiaoyan", "xiaoyu", "catherine", "henry",
"vimary", "vixy", "xiaoqi", "vixf", "xiaomei", "xiaolin",
"xiaorong", "xiaoqian", "xiaokun", "xiaoqiang", "vixying",
"xiaoxin", "nannan", "vils"};
onCreate函数:
@Override
protected void onCreate(Bundle savedInstanceState) {
......
// 初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=APPID");
// 语音合成 1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
mTts = SpeechSynthesizer.createSynthesizer(MainActivity.this,
mTtsInitListener);
// 语音听写1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
mIat = SpeechRecognizer.createRecognizer(this, mTtsInitListener);
// 1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
iatDialog = new RecognizerDialog(this,
mTtsInitListener);
}
语音识别及语音合成:
public void starSpeech() { //语音合成
// 2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
mTts.setParameter(SpeechConstant.VOICE_NAME, voiceName[5]);// 设置发音人
mTts.setParameter(SpeechConstant.SPEED, "50");// 设置语速
mTts.setParameter(SpeechConstant.VOLUME, "80");// 设置音量,范围0~100
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);//设置云端
// 设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm”
// 保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
// 如果不需要保存合成音频,注释该行代码
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
// 3.开始合成
mTts.startSpeaking(result, mSynListener);
// 合成监听器
}
/**
* 初始化参数开始听写
*
* @Description:
*/
private void starWrite() {
// 2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
// 语音识别应用领域(:iat,search,video,poi,music)
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
// 接收语言中文
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 接受的语言是普通话
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
// 设置听写引擎(云端)
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
iatDialog.setListener(mRecognizerDialogListener);
iatDialog.show();
Toast.makeText(getApplication(), "请开始说话…", Toast.LENGTH_SHORT).show();
// 3.开始听写
//mIat.startListening(mRecoListener);
// 听写监听器
}
/**
* 语音听写监听
*/
private RecognizerListener mRecoListener = new RecognizerListener() {
// 听写结果回调接口(返回Json格式结果,用户可参见附录12.1);
// 一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
// 关于解析Json的代码可参见MscDemo中JsonParser类;
// isLast等于true时会话结束。
public void onResult(RecognizerResult results, boolean isLast) {
Log.d(TAG, results.getResultString());
printResult(results);
}
// 会话发生错误回调接口
public void onError(SpeechError error) {
// 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
if (error.getErrorCode() == 10118) {
Toast.makeText(getApplicationContext(), "你好像没有说话哦",
Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), error.getPlainDescription(true),
Toast.LENGTH_SHORT).show();
}// 获取错误码描述}
// 开始录音
public void onBeginOfSpeech() {
Log.d(TAG, "开始说话");
Toast.makeText(getApplicationContext(), "开始说话",
Toast.LENGTH_SHORT).show();
}
// 结束录音
public void onEndOfSpeech() {
Log.d(TAG, "说话结束");
Toast.makeText(getApplicationContext(), "说话结束",
Toast.LENGTH_SHORT).show();
}
// 扩展用接口
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
}
//音量
@Override
public void onVolumeChanged(int volume, byte[] data) {
// TODO Auto-generated method stub
Log.d(TAG, "当前说话音量大小" + volume);
}
};
/**
* 听写UI监听器
*/
private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult results, boolean isLast) {
printResult(results);
}
/**
* 识别回调错误.
*/
public void onError(SpeechError error) {
Toast.makeText(getApplication(), error.getPlainDescription(true), Toast.LENGTH_SHORT).show();
}
};
/**
* 语音合成监听
*/
private SynthesizerListener mSynListener = new SynthesizerListener() {
// 会话结束回调接口,没有错误时,error为null
public void onCompleted(SpeechError error) {
if (error != null) {
Log.d("mySynthesiezer complete code:", error.getErrorCode()
+ "");
} else {
Log.d("mySynthesiezer complete code:", "0");
}
}
// 缓冲进度回调
// percent为缓冲进度0~100,beginPos为缓冲音频在文本中开始位置,endPos表示缓冲音频在文本中结束位置,info为附加信息。
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
}
// 开始播放
public void onSpeakBegin() {
}
// 暂停播放
public void onSpeakPaused() {
}
// 播放进度回调
// percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文本中结束位置.
public void onSpeakProgress(int percent, int beginPos, int endPos) {
}
// 恢复播放回调接口
public void onSpeakResumed() {
}
// 会话事件回调接口
public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
}
};
/**
* 初始化语音合成监听。
*/
private InitListener mTtsInitListener = new InitListener() {
@SuppressLint("ShowToast")
@Override
public void onInit(int code) {
Log.d(TAG, "InitListener init() code = " + code);
if (code != ErrorCode.SUCCESS) {
// showTip("初始化失败,错误码:" + code);
Toast.makeText(getApplicationContext(), "初始化失败,错误码:" + code,
Toast.LENGTH_SHORT).show();
} else {
// 初始化成功,之后可以调用startSpeaking方法
// 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
// 正确的做法是将onCreate中的startSpeaking调用移至这里
}
}
};
语音识别官方参考文档:
语音听写 Android SDK 文档 | 讯飞开放平台文档中心https://www.xfyun.cn/doc/asr/voicedictation/Android-SDK.html#_1%E3%80%81%E7%AE%80%E4%BB%8B 语音合成官方参考文档:
在线语音合成 Android SDK 文档 | 讯飞开放平台文档中心https://www.xfyun.cn/doc/tts/online_tts/Android-SDK.html#_1%E3%80%81%E7%AE%80%E4%BB%8B
百度翻译api的调用(通用翻译API):
1.先注册账号登陆,创建新应用
去百度翻译开放平台注册成为开发者,获得APPID,进行开发者认证(如仅需标准版可跳过),开通通用翻译API服务,创建新应用,需要确定选择开通的服务版本(可以选择个人开发者、企业开发者)、申请认证、填写申请表格,申请表格主要包括*您的应用名称是什么?(名称不超过40个字符)、有无应用相关的介绍链接(不超过40个字符)、请简单介绍下您的应用(不超过200字)、服务器地址(使用服务器调用API的用户,请填写服务器IP地址,APP等客户端不需要填写;多个服务器中间请用“|”隔开,如“113.173.40.255|124.12.122.1”;填写IP后,只有填写的IP才可被调用,请谨慎填写,不超过100个字符)
官方参考文档:
百度翻译开放平台百度翻译开放平台提供通用翻译API、定制化翻译API、图片翻译SDK及语音翻译SDK服务,全面满足开发者的翻译需求。https://fanyi-api.baidu.com/doc/11
2.调用过程
通用翻译API通过HTTP接口对外提供多语种互译服务。您只需要通过调用通用翻译API,传入待翻译的内容,并指定要翻译的源语言(支持源语言语种自动检测)和目标语言种类,就可以得到相应的翻译结果。
通用翻译API HTTP地址:
http://api.fanyi.baidu.com/api/trans/vip/translate
通用翻译API HTTPS地址:
https://fanyi-api.baidu.com/api/trans/vip/translate
输入参数
字段名 | 类型 | 必填参数 | 描述 | 备注 |
---|---|---|---|---|
q | TEXT | Y | 请求翻译query | UTF-8编码 |
from | TEXT | Y | 翻译源语言 | 语言列表(可设置为auto) |
to | TEXT | Y | 译文语言 | 语言列表(不可设置为auto) |
appid | TEXT | Y | APP ID | 可在管理控制台查看 |
salt | TEXT | Y | 随机数 | |
sign | TEXT | Y | 签名 | appid+q+salt+密钥 的MD5值 |
以下字段仅开通了词典、TTS者需填写 | ||||
tts | STRING | N | 是否显示语音合成资源 | tts=0显示,tts=1不显示 |
dict | STRING | N | 是否显示词典资源 | dict=0显示,dict=1不显示 |
以下字段仅开通“我的术语库”用户需填写 | ||||
action | STRING | N | 是否需使用自定义术语干预通用翻译API | 1=是,0=否 |
请求方式:可使用GET或POST方式,如使用POST方式,Content-Type请指定为:application/x-www-form-urlencoded
字符编码:统一采用UTF-8编码格式:
query长度:为保证翻译质量,请将单次请求长度控制在 6000 bytes以内。(汉字约为2000个)
签名生成方法:
签名是为了保证调用安全,使用MD5算法生成的一段字符串,生成的签名长度为32位,签名中的英文字符均为小写格式。
生成方法:
Step1、将请求参数中的 APPID(appid), 翻译query(q, 注意为UTF-8编码), 随机数(salt), 以及平台分配的密钥(可在管理控制台查看),按照 appid+q+salt+密钥 的顺序拼接得到字符串1。
Step2、对字符串1做md5,得到32位小写的sign。
输出参数
返回结果是json格式,包含以下字段:
字段名 | 类型 | 描述 | 备注 |
---|---|---|---|
from | TEXT | 翻译源语言 | 返回用户指定的语言,或自动检测的语言(源语言设为auto时) |
to | TEXT | 译文语言 | 返回用户指定的目标语言 |
trans_result | MIXED LIST | 翻译结果 | 返回翻译结果,包含src 和 dst 字段。 |
src | TEXT | 原文 | |
dst | TEXT | 译文 | |
error_code | Int32 | 错误码 | 仅当出现错误时显示 |
以下字段仅开通词典、TTS资源者可见 | |||
src_tts | 原文tts | mp3格式,暂时无法指定发音 | |
dst_tts | 译文tts | mp3格式,暂时无法指定发音 | |
dict | 中英词典资源 | 返回中文或英文词典资源,包含音标、简明释义等内容 |
接入举例
例如:将英文单词apple翻译成中文:
请求参数:
q=apple
from=en
to=zh
appid=2015063000000001(请替换为您的appid)
salt=1435660288(随机码)
平台分配的密钥: 12345678
生成签名sign:
Step1. 拼接字符串1:
拼接appid=2015063000000001+q=apple+salt=1435660288+密钥=12345678
得到字符串1:"2015063000000001apple143566028812345678"
Step2. 计算签名sign(对字符串1做md5加密)
sign=md5(2015063000000001apple143566028812345678),
得到 sign=f89f9594663708c1605f3d736d01d2d4
拼接完整请求:
http://api.fanyi.baidu.com/api/trans/vip/translate?q=apple&from=en&to=zh&appid=2015063000000001&salt=1435660288&sign=f89f9594663708c1605f3d736d01d2d4
注:也可使用POST方式,如POST方式传送,Content-Type请指定为:application/x-www-form-urlencoded
语言列表
源语言语种不确定时可设置为 auto,目标语言语种不可设置为auto。但对于非常用语种,语种自动检测可能存在误差。
语言简写 | 名称 |
---|---|
auto | 自动检测 |
zh | 中文 |
en | 英语 |
yue | 粤语 |
wyw | 文言文 |
jp | 日语 |
kor | 韩语 |
fra | 法语 |
spa | 西班牙语 |
th | 泰语 |
ara | 阿拉伯语 |
ru | 俄语 |
pt | 葡萄牙语 |
de | 德语 |
it | 意大利语 |
el | 希腊语 |
nl | 荷兰语 |
pl | 波兰语 |
bul | 保加利亚语 |
est | 爱沙尼亚语 |
dan | 丹麦语 |
fin | 芬兰语 |
cs | 捷克语 |
rom | 罗马尼亚语 |
slo | 斯洛文尼亚语 |
swe | 瑞典语 |
hu | 匈牙利语 |
cht | 繁体中文 |
vie | 越南语 |
错误码列表
当翻译结果无法正常返回时,请参考下表处理:
错误码 | 含义 | 解决方法 |
---|---|---|
52000 | 成功 | |
52001 | 请求超时 | 重试 |
52002 | 系统错误 | 重试 |
52003 | 未授权用户 | 检查您的 appid 是否正确,或者服务是否开通 |
54000 | 必填参数为空 | 检查是否少传参数 |
54001 | 签名错误 | 请检查您的签名生成方法 |
54003 | 访问频率受限 | 请降低您的调用频率 |
54004 | 账户余额不足 | 请前往管理控制台为账户充值 |
54005 | 长query请求频繁 | 请降低长query的发送频率,3s后再试 |
58000 | 客户端IP非法 | 检查个人资料里填写的 IP地址 是否正确 可前往管理控制平台修改 IP限制,IP可留空 |
58001 | 译文语言方向不支持 | 检查译文语言是否在语言列表里 |
58002 | 服务当前已关闭 | 请前往管理控制台开启服务 |
90107 | 认证未通过或未生效 | 请前往我的认证查看认证进度 |
3.相关代码
引入依赖:
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
翻译方法:
public void translate() {
//准备请求百度翻译接口需要的参数
String word = fanyiWords;//需查询的单词 q
String from = "auto";//源语种 en 英语 zh 中文
//String中英文占用一个字节,中文占用两个字节,
//利用String的这个存储特性可以用来判断String中有没有中文。
// to = "zh"; //没有汉字 英译中
to = "en";//含有汉字 中译英
String appid = "appid";//appid 管理控制台有
String salt = (int) (Math.random() * 100 + 1) + "";//随机数这里范围是[0,100]整数无强制要求
String key = "secret key";//密钥 管理控制台有
String secretKey = appid + word + salt + key;// secretKey = appid+q+salt+密钥
String sign = MD5Utils.getMD5Code(secretKey);// 签名 = secretKey 的MD5加密32位字母小写
Log.d(TAG, "secretKey:" + secretKey);
Log.d(TAG, "sign: " + sign);
Retrofit retrofitBaidu = new Retrofit.Builder()
.baseUrl("https://fanyi-api.baidu.com/api/trans/vip/")
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
.build();
BaiduTranslateService baiduTranslateService =retrofitBaidu.create(BaiduTranslateService.class);
Call<RespondBean> call = baiduTranslateService.translate(word, from, to, appid, salt, sign);
call.enqueue(new Callback<RespondBean>() {
@Override
public void onResponse(Call<RespondBean> call, Response<RespondBean> response) {
//请求成功
Log.d(TAG, "onResponse: 请求成功");
RespondBean respondBean = response.body();//返回的JSON字符串对应的对象
result = respondBean.getTrans_result().get(0).getDst();//获取翻译的字符串String
Log.d(TAG, "中译英结果" + result);
}
@Override
public void onFailure(Call<RespondBean> call, Throwable t) {
//请求失败 打印异常
Log.d(TAG, "onResponse: 请求失败 " + t);
}
});
}
BaiduTranslateService
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
//源URL https://fanyi-api.baidu.com/api/trans/vip/translate
//参数如下
// String q 英文单词/中文
// String from 原始语种 zh中文/eh英文
// String to 目标语种 zh中文/eh英文
// String from zh中文/eh英文
// String appid 你的appid
// String salt 随机数(整形转字符串)
// String sign 签名 32位字母小写MD5编码的 appid+q+salt+密钥
public interface BaiduTranslateService {
//翻译接口
//表示提交表单数据,@Field注解键名
//适用于数据量少的情况
@POST("translate")
@FormUrlEncoded
Call<RespondBean> translate(@Field("q") String q, @Field("from") String from, @Field("to") String to, @Field("appid") String appid, @Field("salt") String salt,
@Field("sign") String sign);
}
MD5Utils
import java.security.MessageDigest;
/**
* 加密解密工具类(对字符串加密) MD5加密
*/
public class MD5Utils {
/**
* MD5加密算法使用 对字符串加密
*
* @param info 参数为需要加密的String
* @return 返回加密后的String
*/
public static String getMD5Code(String info) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(info.getBytes("utf-8"));//设置编码格式
byte[] encryption = md5.digest();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < encryption.length; i++) {
if (Integer.toHexString(0xff & encryption[i]).length() == 1) {
stringBuffer.append("0").append(Integer.toHexString(0xff & encryption[i]));
} else {
stringBuffer.append(Integer.toHexString(0xff & encryption[i]));
}
}
return stringBuffer.toString();
} catch (Exception e) {
return "MD5加密异常";
}
}
}
RespondBean:
import java.util.List;
public class RespondBean {
/**
* from : zh
* to : en
* trans_result : [{"src":"你好","dst":"Hello"}]
*/
private String from;
private String to;
private List<TransResultBean> trans_result;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public List<TransResultBean> getTrans_result() {
return trans_result;
}
public void setTrans_result(List<TransResultBean> trans_result) {
this.trans_result = trans_result;
}
public static class TransResultBean {
/**
* src : 你好
* dst : Hello
*/
private String src;
private String dst;
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public String getDst() {
return dst;
}
public void setDst(String dst) {
this.dst = dst;
}
}
}
百度通用翻译API官方技术文档:百度翻译开放平台百度翻译开放平台提供通用翻译API、定制化翻译API、拍照翻译SDK及语音翻译SDK服务,全面满足开发者的翻译需求。https://fanyi-api.baidu.com/api/trans/product/apidoc#joinFile
最后
以上就是含糊白开水为你收集整理的实现简单的中英互译的安卓App的全部内容,希望文章能够帮你解决实现简单的中英互译的安卓App所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复