讯飞的集成不再赘述,因为他对用户挺友好的

但是使用,最好自己写一个工具类,下面是两个我写的工具类


语音识别工具类

public class RecognizerManager implements RecognizerListener {

    //单例

    private RecognizerManager() {}

    private static class SingletonHolder {
        final static RecognizerManager sm = new RecognizerManager();
        volatile static AtomicBoolean isInitialized = new AtomicBoolean(false);
    }

    public static RecognizerManager getInstance() { return SingletonHolder.sm;}

    //初始化

    public static void init(Context applicationContext) {
        if (applicationContext instanceof Activity) return;

        if (!SingletonHolder.isInitialized.compareAndSet(false, true)) {
            synchronized (SingletonHolder.sm) { SingletonHolder.sm.initInternal(applicationContext);}
        }
    }

    //内部初始化

    private void initInternal(Context applicationContext) {
        SpeechUtility.createUtility(applicationContext, Constant.SPEECH_ID);

        SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(applicationContext, null);
        mIat.setParameter(SpeechConstant.DOMAIN, "iat");
        mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");

        mIat.startListening(this);
    }

    //观察者(他们可以接收到语音)

    private List<Listener> listenerList;

    public void addListener(Listener listener) {
        if (listenerList == null) listenerList = new ArrayList<>();
        listenerList.add(listener);
    }

    public void removeListener(Listener listener) {
        if (listenerList == null) return;
        if (listenerList.contains(listener)) listenerList.remove(listener);
    }

    public interface Listener { void onGetWord(String word);}

    //处理我们说的话

    private StringBuilder builder = new StringBuilder();

    @Override
    public void onVolumeChanged(int i, byte[] bytes) {}

    @Override
    public void onBeginOfSpeech() {}

    @Override
    public void onEndOfSpeech() { builder.delete(0, builder.length());}

    @Override
    public void onResult(RecognizerResult recognizerResult, boolean b) {
        //json解析最好用ali的 业界公认第一快
        String json = recognizerResult.getResultString();
        JSONObject jo = JSONObject.parseObject(json);

        JSONArray ja1 = jo.getJSONArray("ws");
        for (int i = 0; i < ja1.size(); i++) {
            JSONObject tempJo = ja1.getJSONObject(i);
            JSONArray ja2 = tempJo.getJSONArray("cw");
            for (int j = 0; j < ja2.size(); j++) {
                JSONObject tempJo2 = ja2.getJSONObject(j);
                String s = tempJo2.getString("w");
                builder.append(s);
            }
        }

        if (listenerList != null && listenerList.size() != 0)
            for (int i = 0; i < listenerList.size(); i++)
                listenerList.get(i).onGetWord(builder.toString());
    }

    @Override
    public void onError(SpeechError speechError) {
//        Log.i(Constant.TAG, "语音错误:" + speechError.getErrorDescription());
    }

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


Application的onCreate中(因为项目需求,我们在整个app运行的时候,都能进行语音操作,读者可自行缩短life cycle)

//初始化语音播报和语音识别
VoicerManager.init(getApplicationContext());
RecognizerManager.init(getApplicationContext());


Activity注册观察者

@Override
protected void onPause() {
    super.onPause();
    RecognizerManager.getInstance().removeListener(this);
}

@Override
protected void onResume() {
    super.onResume();
    RecognizerManager.getInstance().addListener(this);
}


一个应用场景

//拿到我们说的话

private static final String OPEN_NAVIGATION = "打开导航";
private static final String OPEN_ENTERTAINMENT = "打开娱乐";
private static final String OPEN_SETTINGS = "打开设置";

private static final String ERROR = "您说的不符合规范,应该说:打开地图、打开音乐等";

@Override
public void onGetWord(String word) {
    if (word.contains(OPEN_NAVIGATION))

        startActivity(MapActivity.class);

    else if (word.contains(OPEN_ENTERTAINMENT))

        startActivity(EntertainmentActivity.class);

    else if (word.contains(OPEN_SETTINGS))

        startActivity(SettingActivity.class);

    else

        speak(ERROR);
}


语音合成

public class SpeakerManager implements SynthesizerListener {

    //单例

    private SpeakerManager() {}

    static class SingletonHolder {
        static final SpeakerManager vm = new SpeakerManager();
        volatile static AtomicBoolean isInitialized = new AtomicBoolean(false);
    }

    public static SpeakerManager getInstance() { return SingletonHolder.vm;}

    public static void init(Context applicationContext) {
        if (applicationContext instanceof Activity) return;

        SpeakerManager instance = SingletonHolder.vm;
        if (!SingletonHolder.isInitialized.compareAndSet(false, true)) {
            SingletonHolder.isInitialized.set(true);
            synchronized (SingletonHolder.vm) { SingletonHolder.vm.initInternal(applicationContext)}
        }
    }

    //--------------------初始化-----------------------

    private SpeechSynthesizer mTts;

    private void initInternal(Context applicationContext) {
        mTts = SpeechSynthesizer.createSynthesizer(applicationContext, null);

        mTts.setParameter(SpeechConstant.PARAMS, null);// 清空参数
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);// 设置在线云端
        mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");// 设置发音人
        mTts.setParameter(SpeechConstant.SPEED, "50");// 设置发音语速
        mTts.setParameter(SpeechConstant.PITCH, "50");// 设置音调
        mTts.setParameter(SpeechConstant.VOLUME, "100");// 设置合成音量
        mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");// 设置播放器音频流类型
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");// 设置播放合成音频打断音乐播放,默认为true

    }

    //--------------------api(不用解决并发,为了保证语音实时性)-----------------------

    public void speak(String msg) {
        mTts.startSpeaking(msg, SpeakerManager.this);
    }

    //--------------------语音播放回调,暂时用不到呀-----------------------

    @Override
    public void onSpeakBegin() {

    }

    @Override
    public void onBufferProgress(int i, int i1, int i2, String s) {

    }

    @Override
    public void onSpeakPaused() {

    }

    @Override
    public void onSpeakResumed() {

    }

    @Override
    public void onSpeakProgress(int i, int i1, int i2) {
//        if (i > 90) {
//        }
    }

    @Override
    public void onCompleted(SpeechError speechError) {

    }

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

    }

    //--------------------生命周期-----------------------

    public void onDestroy() {
        if (mTts != null) {
            if (mTts.isSpeaking()) {
                mTts.stopSpeaking();
            }
            mTts.destroy();  //退出时释放
            mTts = null;
        }
    }
}


这个类直接拿到实例调用speak就能说话了

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐