背景:1,前段時間做了百度的語音合成,2,后來又做了語音聽寫,3,現(xiàn)在要做語音喚醒
問題:
語音喚醒的代碼,總是提示“has no license”,很是郁悶,明明“語音合成”,“語音聽寫”都沒有毛病的,語音喚醒為啥會出問題呢。
找原因:

官網(wǎng)說,“appId appKey appSecret包名(applicationId)4個必須完全正確,才能自動下載正式授權(quán)文件”
所以,一定是這4個位置出現(xiàn)了問題(不要糾結(jié)為什么 語音合成,語音聽寫是正常的)
解決思路:
1,首先嘗試了,將官網(wǎng)demo的appId appKey appSecret,applicationId,放進自己項目里,發(fā)現(xiàn)語音喚醒可以正常使用;
2,又嘗試,將自己項目里的appId appKey appSecret,applicationId,放進官網(wǎng)的項目里,發(fā)現(xiàn)語音喚醒 不能正常使用
3,驗證了原因:就是自己項目的appId appKey appSecret,applicationId有問題
4,前面講了,我的語音合成,語音聽寫都是ok的,所以我堅信我的appId appKey appSecret,applicationId,不會出問題
5,想了一夜,我認為是不是語音合成,語音喚醒,要用2套不同的appId appKey appSecret,于是開始嘗試,語音喚醒的appId appKey appSecret又重新用包名建了一個應(yīng)用,竟然完美解決了。
最終成果:
我將語音喚醒,對話框輸入語音,語音喚醒后對話框輸入語音,集成在一個界面,代碼如下:
/**
* 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參數(shù)。
? ? ? ? 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的輸入?yún)?shù)
? ? ? ? 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:// 初始狀態(tài)
//禁止語音喚醒
? ? ? ? ? ? ? ? myWakeup.stop();
? ? ? ? ? ? ? ? //開始錄音
? ? ? ? ? ? ? ? startSpeech();
? ? ? ? ? ? ? ? status =STATUS_WAITING_READY;
break;
? ? ? ? ? ? case STATUS_WAITING_READY:// 調(diào)用本類的start方法后,即輸入START事件后,等待引擎準(zhǔn)備完畢。
? ? ? ? ? ? case STATUS_READY:// 引擎準(zhǔn)備完畢。
? ? ? ? ? ? case STATUS_SPEAKING:// 用戶開始講話
? ? ? ? ? ? case STATUS_FINISHED:// 一句話識別語音結(jié)束
? ? ? ? ? ? case STATUS_RECOGNITION:// 識別中
? ? ? ? ? ? ? ? stop();
? ? ? ? ? ? ? ? status =STATUS_STOPPED; // 引擎識別中
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case STATUS_LONG_SPEECH_FINISHED:// 長語音識別結(jié)束
? ? ? ? ? ? case STATUS_STOPPED:// 引擎識別中
? ? ? ? ? ? ? ? cancel();
? ? ? ? ? ? ? ? status =STATUS_NONE; // 識別結(jié)束,回到初始狀態(tài)
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
break;
? ? ? ? }
}
@Override
? ? protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e("handleMsg= ", "onActivityResult");
? ? ? ? if (requestCode ==2) {
//停止喚醒
? ? ? ? ? ? stop();
? ? ? ? ? ? String message ="對話框的識別結(jié)果:";
? ? ? ? ? ? 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 +="沒有結(jié)果";
? ? ? ? ? ? }
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中的狀態(tài)回調(diào)
? ? ? ? ? ? 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 以上需要動態(tài)申請權(quán)限
*/
? ? 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);
? ? ? ? ? ? ? ? // 進入到這里代表沒有權(quán)限.
? ? ? ? ? ? }
}
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以上動態(tài)授權(quán)的回調(diào),用戶自行實現(xiàn)。
? ? }
/**
* 開始錄音后,手動點擊“停止”按鈕。
* SDK會識別不會再識別停止后的錄音。
* 基于DEMO集成4.1 發(fā)送停止事件 停止錄音
*/
? ? protected void stop() {
myRecognizer.stop();
? ? ? ? //停止喚醒
? ? ? ? myWakeup.stop();
? ? }
/**
* 開始錄音后,手動點擊“取消”按鈕。
* SDK會取消本次識別,回到原始狀態(tài)。
* 基于DEMO集成4.2 發(fā)送取消事件 取消本次識別
*/
? ? protected void cancel() {
myRecognizer.cancel();
? ? ? ? //停止喚醒
? ? ? ? myWakeup.stop();
? ? }
@Override
? ? protected void onResume() {
super.onResume();
? ? ? ? //開始喚醒 (如果將此代碼注釋,則該界面相當(dāng)于 對話框輸入語音界面)
? ? ? ? startWakeup();
? ? }
@Override
? ? protected void onDestroy() {
myRecognizer.release();
? ? ? ? //停止喚醒
? ? ? ? myWakeup.release();
? ? ? ? // BluetoothUtil.destory(this); // 藍牙關(guān)閉
? ? ? ? super.onDestroy();
? ? }
}