背景:1,前段时间做了百度的语音合成,2,后来又做了语音听写,3,现在要做语音唤醒
问题:
语音唤醒的代码,总是提示“has no license”,很是郁闷,明明“语音合成”,“语音听写”都没有毛病的,语音唤醒为啥会出问题呢。
找原因:
官网说,“appId appKey appSecret包名(applicationId)4个必须完全正确,才能自动下载正式授权文件”
所以,一定是这4个位置出现了问题(不要纠结为什么 语音合成,语音听写是正常的)
解决思路:
1,首先尝试了,将官网demo的appId appKey appSecret,applicationId,放进自己项目里,发现语音唤醒可以正常使用;
2,又尝试,将自己项目里的appId appKey appSecret,applicationId,放进官网的项目里,发现语音唤醒 不能正常使用
3,验证了原因:就是自己项目的appId appKey appSecret,applicationId有问题
4,前面讲了,我的语音合成,语音听写都是ok的,所以我坚信我的appId appKey appSecret,applicationId,不会出问题
5,想了一夜,我认为是不是语音合成,语音唤醒,要用2套不同的appId appKey appSecret,于是开始尝试,语音唤醒的appId appKey appSecret又重新用包名建了一个应用,竟然完美解决了。
最终成果:
我将语音唤醒,对话框输入语音,语音唤醒后对话框输入语音,集成在一个界面,代码如下:
/**
* Created by 000098 on 2020/3/22。
* Description 自定义的界面,含:1 - 唤醒功能,2 - 对话框输入功能, 3 - 唤醒后对话框输入功能
*
* @author 000098
*/
public class WakeUpAndSpeechextends AppCompatActivityimplements IStatus {
protected TextViewtxtLog;
protected Buttonbtn;
protected Buttonsetting;
protected TextViewtxtResult;
protected int textViewLines =0;
//通用的
protected Handlerhandler;
protected MyRecognizermyRecognizer;
//语音输入对话框的
private CommonRecogParamsapiParams;
private DigitalDialogInputinput;
private ChainRecogListenerchainRecogListener;
//语音唤醒的
protected MyWakeupmyWakeup;
private int status =STATUS_NONE;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 通用的
InFileStream.setContext(this);
setContentView(R.layout.common_without_setting);
initView();
handler =new Handler() {
/*
* @param msg
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
handleMsg(msg);
}
};
MyLogger.setHandler(handler);
initPermission();
IRecogListener recogListener =new MessageStatusRecogListener(handler);
myRecognizer =new MyRecognizer(this, recogListener);
//语音输入对话框的
chainRecogListener =new ChainRecogListener();
chainRecogListener.addListener(new MessageStatusRecogListener(handler));
myRecognizer.setEventListener(chainRecogListener); // 替换掉原来的listener
initApiParams();
//语音唤醒的
IWakeupListener wakeupListener1 =new RecogWakeupListener(handler);
myWakeup =new MyWakeup(this, wakeupListener1);
IWakeupListener wakeupListener2 =new RecogWakeupListener(handler);
myWakeup.setEventListener(wakeupListener2); // 替换原来的 listener
}
public void initApiParams() {
apiParams =new OnlineRecogParams();
apiParams.initSamplePath(this);
}
protected MapfetchParams() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
// 上面的获取是为了生成下面的Map, 自己集成时可以忽略
Map params =apiParams.fetch(sp);
// 集成时不需要上面的代码,只需要params参数。
return params;
}
/**
* 1 - 唤醒功能
*/
protected void startWakeup() {
Map params =new HashMap();
params.put(SpeechConstant.WP_WORDS_FILE, "assets:///WakeUp.bin");
myWakeup.start(params);
}
protected void startSpeech() {
// 此处params可以打印出来,直接写到你的代码里去,最终的json一致即可。
final Map params = fetchParams();
// BaiduASRDigitalDialog的输入参数
input =new DigitalDialogInput(myRecognizer, chainRecogListener, params);
BaiduASRDigitalDialog.setInput(input); // 传递input信息,在BaiduASRDialog中读取,
Intent intent =new Intent(this, BaiduASRDigitalDialog.class);
startActivityForResult(intent, 2);
}
/**
* 2 - 对话框输入功能
*/
protected void startVoice() {
switch (status) {
case STATUS_NONE:// 初始状态
//禁止语音唤醒
myWakeup.stop();
//开始录音
startSpeech();
status =STATUS_WAITING_READY;
break;
case STATUS_WAITING_READY:// 调用本类的start方法后,即输入START事件后,等待引擎准备完毕。
case STATUS_READY:// 引擎准备完毕。
case STATUS_SPEAKING:// 用户开始讲话
case STATUS_FINISHED:// 一句话识别语音结束
case STATUS_RECOGNITION:// 识别中
stop();
status =STATUS_STOPPED; // 引擎识别中
break;
case STATUS_LONG_SPEECH_FINISHED:// 长语音识别结束
case STATUS_STOPPED:// 引擎识别中
cancel();
status =STATUS_NONE; // 识别结束,回到初始状态
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e("handleMsg= ", "onActivityResult");
if (requestCode ==2) {
//停止唤醒
stop();
String message ="对话框的识别结果:";
if (resultCode ==RESULT_OK) {
ArrayList results = data.getStringArrayListExtra("results");
if (results !=null && results.size() >0) {
String str = results.get(0).toString().replace(",", "");
message += str;
}
}else {
message +="没有结果";
}
Log.e("handleMsg= ", message);
}
}
protected void handleMsg(Message msg) {
if (txtLog !=null && msg.obj !=null) {
textViewLines++;
if (textViewLines >100) {
textViewLines =0;
txtLog.setText("");
}
txtLog.append(msg.obj.toString() +"\n");
}
if (msg.what ==STATUS_WAKEUP_SUCCESS) {
//3 - 唤醒后对话框输入功能
Log.e("handleMsg", "STATUS_WAKEUP_SUCCESS");
startSpeech();
return;
}
switch (msg.what) {// 处理MessageStatusRecogListener中的状态回调
case STATUS_FINISHED:
if (msg.arg2 ==1) {
Log.e("handleMsg", msg.obj.toString());
}
status = msg.what;
break;
case STATUS_NONE:
case STATUS_READY:
case STATUS_SPEAKING:
case STATUS_RECOGNITION:
status = msg.what;
break;
default:
break;
}
}
protected void initView() {
txtResult = findViewById(com.baidu.aip.asrwakeup3.uiasr.R.id.txtResult);
txtLog = findViewById(com.baidu.aip.asrwakeup3.uiasr.R.id.txtLog);
btn = findViewById(com.baidu.aip.asrwakeup3.uiasr.R.id.btn);
setting = findViewById(com.baidu.aip.asrwakeup3.uiasr.R.id.setting);
//
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startVoice();
}
});
}
/**
* android 6.0 以上需要动态申请权限
*/
private void initPermission() {
String[] permissions = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
ArrayList toApplyList =new ArrayList<>();
for (String perm : permissions) {
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {
toApplyList.add(perm);
// 进入到这里代表没有权限.
}
}
String[] tmpList =new String[toApplyList.size()];
if (!toApplyList.isEmpty()) {
ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// 此处为android 6.0以上动态授权的回调,用户自行实现。
}
/**
* 开始录音后,手动点击“停止”按钮。
* SDK会识别不会再识别停止后的录音。
* 基于DEMO集成4.1 发送停止事件 停止录音
*/
protected void stop() {
myRecognizer.stop();
//停止唤醒
myWakeup.stop();
}
/**
* 开始录音后,手动点击“取消”按钮。
* SDK会取消本次识别,回到原始状态。
* 基于DEMO集成4.2 发送取消事件 取消本次识别
*/
protected void cancel() {
myRecognizer.cancel();
//停止唤醒
myWakeup.stop();
}
@Override
protected void onResume() {
super.onResume();
//开始唤醒 (如果将此代码注释,则该界面相当于 对话框输入语音界面)
startWakeup();
}
@Override
protected void onDestroy() {
myRecognizer.release();
//停止唤醒
myWakeup.release();
// BluetoothUtil.destory(this); // 蓝牙关闭
super.onDestroy();
}
}
网友评论