Android 科大讯飞 在线和离线语音听写

效果图:

这里写图片描述

参考资料

http://blog.csdn.net/imhxl/article/details/50854146

项目里要用语音听写,想到了科大讯飞,参考上面的资料完成了最简单的在线有UI的语音识别,后面想要改成离线也可以使用。参考下面的文章

http://blog.csdn.net/q4878802/article/details/47834601

下载好语记和离线资源之后,想要改成有UI的RecognizerDialog离线语音听写,但是没成功,试了一下没有UI的SpeechRecognizer,发现可以,只需在设置参数的时候加上一句

recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口

就可以使用了。可能是RecognizerDialog带有UI界面,已经默认写成在线的了吧
下面只贴出主活动的代码,其他参考上面的资料

package com.example.administrator.voicerecognition;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
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.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;

public class MainActivity extends AppCompatActivity {
    private Button btn_voiceRec,btn_voiceRecOffline;
    private RecognizerDialog iatDialog=null;
    private SpeechRecognizer recognizer=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid
        btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec);
        btn_voiceRec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (iatDialog!=null){
                    iatDialog.cancel();
                    iatDialog.destroy();
                }
                startDialogOnline();
            }
        });
        btn_voiceRecOffline= (Button) findViewById(R.id.btn_voiceRecOffline);
        btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                if (recognizer!=null){
//                    recognizer.cancel();
//                    recognizer.destroy();
//                }
                startNoDialogOffline();
            }
        });
    }

    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            Log.d("tag", "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                Log.d("tag", "初始化失败,错误码:" + code);
            }
        }
    };

    public void startDialogOnline() {
        //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        iatDialog = new RecognizerDialog(this, mInitListener);
        //2.设置听写参数

        iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin ");


        //3.设置回调接口
        iatDialog.setListener(new RecognizerDialogListener() {
            @Override
            public void onResult(RecognizerResult recognizerResult, boolean b) {
                if (!b) {
                    String json = recognizerResult.getResultString();
                    String str = JsonParser.parseIatResult(json);
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(SpeechError speechError) {
                Log.d("error", speechError.toString());
            }
        });
        //4.开始听写
        iatDialog.show();
    }


    private void startNoDialogOffline(){
        //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        recognizer = SpeechRecognizer.createRecognizer(this,null);
        //2.设置听写参数

        recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口


        recognizer.setParameter(SpeechConstant.DOMAIN, "iat");//参数设为语音听写
        recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");//中文
        recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");//普通话

        //3.设置回调接口
        recognizer.startListening(new RecognizerListener() {
            @Override
            public void onVolumeChanged(int i, byte[] bytes) {

            }

            @Override
            public void onBeginOfSpeech() {

            }

            @Override
            public void onEndOfSpeech() {

            }

            @Override
            public void onResult(RecognizerResult recognizerResult, boolean isLast) {
                if (isLast) {
                    String json = recognizerResult.getResultString();
                    String str = JsonParser.parseIatResult(json);
                    Log.d("tag",str);
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(SpeechError speechError) {
                Log.d("error", speechError.toString());
            }

            @Override
            public void onEvent(int i, int i1, int i2, Bundle bundle) {

            }
        });
    }
}

—————————————————————————————————

2016.11.2更新

离线语音做了个简单的UI,效果如图:

这里写图片描述

完整代码如下,改动部分已注释:

package com.example.administrator.voicerecognition;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
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.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;

public class MainActivity extends AppCompatActivity {
    private Button btn_voiceRec,btn_voiceRecOffline;
    private RecognizerDialog iatDialog=null;
    private SpeechRecognizer recognizer=null;
    //新增对话框和语音听写完成标志------------------
    private ProgressDialog pDialog=null;
    private boolean isFinish=false;
    //-----------------------------------
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid
        btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec);
        btn_voiceRec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (iatDialog!=null){
                    iatDialog.cancel();
                    iatDialog.destroy();
                }
                startDialogOnline();
            }
        });
        btn_voiceRecOffline= (Button) findViewById(R.id.btn_voiceRecOffline);
        btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                if (recognizer!=null){
//                    recognizer.cancel();
//                    recognizer.destroy();
//                }
                startNoDialogOffline();
                //显示对话框----------------
                showProgressDialog();
                //----------------------
            }
        });
    }

    //对话框显示方法-----------------------------------
    private void showProgressDialog() {
        pDialog = new ProgressDialog(MainActivity.this);

        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDialog.setProgress(100);
        pDialog.setMessage("请稍等...");
        pDialog.setIndeterminate(false);
        pDialog.show();

        WindowManager.LayoutParams lp = pDialog.getWindow().getAttributes();
        lp.gravity = Gravity.CENTER;
        Window win = pDialog.getWindow();
        win.setAttributes(lp);

        new Thread(new Runnable() {

            @Override
            public void run() {
                //long startTime = System.currentTimeMillis();
                int progress = 0;

                //while (System.currentTimeMillis() - startTime < 1000) {
                //语音听写完成后,释放对话框
                while (!isFinish) {
                    try {
                        progress += 10;
                        pDialog.setProgress(progress);
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        pDialog.dismiss();
                    }
                }

                pDialog.dismiss();
                isFinish=false;
            }
        }).start();
    }
//--------------------------------------------------------

    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            Log.d("tag", "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                Log.d("tag", "初始化失败,错误码:" + code);
            }
        }
    };

    public void startDialogOnline() {
        //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        iatDialog = new RecognizerDialog(this, mInitListener);
        //2.设置听写参数

        iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin ");


        //3.设置回调接口
        iatDialog.setListener(new RecognizerDialogListener() {
            @Override
            public void onResult(RecognizerResult recognizerResult, boolean isLast) {
                if (!isLast) { 
                    String json = recognizerResult.getResultString();
                    String str = JsonParser.parseIatResult(json);
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(SpeechError speechError) {
                Log.d("error", speechError.toString());
            }
        });
        //4.开始听写
        iatDialog.show();
    }


    private void startNoDialogOffline(){
        //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        recognizer = SpeechRecognizer.createRecognizer(this,null);
        //2.设置听写参数

        recognizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);//调用语记接口


        recognizer.setParameter(SpeechConstant.DOMAIN, "iat");//参数设为语音听写
        recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");//中文
        recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");//普通话

        //3.设置回调接口
        recognizer.startListening(new RecognizerListener() {
            @Override
            public void onVolumeChanged(int i, byte[] bytes) {

            }

            @Override
            public void onBeginOfSpeech() {

            }

            @Override
            public void onEndOfSpeech() {

            }

            @Override
            public void onResult(RecognizerResult recognizerResult, boolean isLast) {
                if (isLast) {
                    String json = recognizerResult.getResultString();
                    String str = JsonParser.parseIatResult(json);
                    Log.d("tag",str);
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                    //语音听写完成标志---------------------------
                    isFinish=true;
                    //------------------------------------------
                }
            }

            @Override
            public void onError(SpeechError speechError) {
                Log.d("error", speechError.toString());
            }

            @Override
            public void onEvent(int i, int i1, int i2, Bundle bundle) {

            }
        });
    }
}

注:经过多次测试后发现,第一次点击按钮离线语音听写无法识别,第二次点击按钮才可正常实现听写,之后都可以正常听写,这个bug目前还没有解决

—————————————————————————————————

2016.11.6 更新

第一次离线语音听写无反应bug的解决办法:在onCreat()里先执行一次,不显示UI,这样再点击就是第二次了。。。虽然很蠢,但是功能上算是实现了,后面有时间再仔细想想更好的办法

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SpeechUtility.createUtility(this, "appid=xxx");//替换为实际的appid
        btn_voiceRec = (Button) findViewById(R.id.btn_voiceRec);
        btn_voiceRec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startDialogOnline();
            }
        });
        btn_voiceRecOffline = (Button) findViewById(R.id.btn_voiceRecOffline);
    //先听写一次----------------------------
        startNoDialogOffline();
        //------------------------------------
        btn_voiceRecOffline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startNoDialogOffline();
                showProgressDialog();
            }
        });
    }

注:调试过程中又发现,在单独使用在线的情况下,在线的RecognizerDialogListener的onResult()会调用两次,输出两个str,第一个是听写内容,第二个是标点符号。如果是if (!isLast),那么输出的是听写内容,如果是if (isLast),输出的是标点符号。很显然,需要的是听写内容,这时要用if (!isLast)。

如果和离线的混用,就像上面一样,在onCreat()里先执行了一次startNoDialogOffline(),那么经测试RecognizerDialogListener的onResult()只会调用一次,输出一个str,听写内容和标点符号连在一起的(具体原因不清楚),这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。

单独使用离线的情况下,RecognizerListener的onResult()是只会调用一次,输出一个str。这时候如果是if (!isLast),就不会有输出了。所以这里要用if (isLast)。

所以说在线的要和离线的分开使用,本文只是个例子,实际使用过程中也不会同时使用。简单来说,在线用if (!isLast)判断,离线用if (isLast)判断

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页