语音助手

一导入相关的包

二添加相应的权限

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.voice"
    android:versionCode="1"
    android:versionName="1.0" >

    <!-- 连接网络权限,用于执行云端语音能力 -->
    <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-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

三整体布局

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:cacheColorHint="@android:color/transparent"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:layout_weight="1" />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bottom_bar" >

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:onClick="start"
            android:background="@drawable/btn_selector"
            android:text="语音识别" />
    </RelativeLayout>

</LinearLayout>

四创建公共类(语音合成和识别)

VoiceUtils.java

package com.example.voice;

import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;

import android.content.Context;

public class VoiceUtils {
    private Context context;

    public VoiceUtils(Context context) {
        this.context = context;
        // 将“12345678”替换成您申请的APPID,申请地址:http://open.voicecloud.cn
        SpeechUtility.createUtility(context, SpeechConstant.APPID + "= 574d92ab");
    }

    public void listen(RecognizerDialogListener Listener) {
        // 1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        RecognizerDialog iatDialog = new RecognizerDialog(context, null);
        // 2.设置听写参数,同上节
        iatDialog.setParameter(SpeechConstant.DOMAIN, "iat");
        iatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        iatDialog.setParameter(SpeechConstant.ACCENT, "mandarin ");
        // 3.设置回调接口
        iatDialog.setListener(Listener);
        // 4.开始听写
        iatDialog.show();

        // //1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        // SpeechRecognizer mIat= SpeechRecognizer.createRecognizer(context,
        // null);
        // //2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
        // mIat.setParameter(SpeechConstant.DOMAIN, "iat");
        // mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
        // //3.开始听写
        // mIat.startListening(mRecoListener);
        // //听写监听器
    }

    public void speak(String word) {
        // 1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
        SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer(context, null);
        // 2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
        mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");// 设置发音人
        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(word, null);
        // 合成监听器

    }
}

五获取按钮的监听,触发公共类的listen(),

public void start(View v) {
        voiceUtils.listen(new MyRecognizerDialogListener());
    }

而MyRecognizerDialogListener类里面有个函数

public void onResult(RecognizerResult result, boolean isLast)

获取的result是json格式,需要进行解析(建立相应的bean类),首先是字符与字符之间的拼接,后是句与句的拼接,这样子才能组成一段话。此外在组成一段话后,需要清空之前的话,新建new StringBuffer()即可,随后对ListView添加数据,建立适配器Myadapter(),最后设置回答内容,并且读出来。

VoiceBean.java(json格式的bean)

package com.example.voice;

import java.util.List;

public class VoiceBean {
    public int bg;
    public int ed;
    public boolean ls;
    public int sn;
    public List<WS> ws;
    public class WS{
        public int bg;
        public List<CW> cw;
    }
    public class CW{
        public double sc;
        public String w;
    }
}

Conversation.java(对布局中显示的数据)

package com.example.voice;

public class Conversation {
    public String word;//展示的文字
    public boolean isAsker;//是否是问题
    public int imgId;//-1无图片 
//    创建构造方法
    public Conversation(String word, boolean isAsker, int imgId) {
        super();
        this.word = word;
        this.isAsker = isAsker;
        this.imgId = imgId;
    }

}

Resource.java(布局中回答的图片文字内容)

package com.example.voice;

public class Resource {
    public static int[] imgIds = new int[] { R.drawable.cyx, R.drawable.mm14,
            R.drawable.mm19, R.drawable.mm21, R.drawable.mm23
    };
    public static String[] words = new String[]{
        "就是这样子",
        "哈哈哒",
        "500",
        "烦烦烦",
        "夜夜夜夜"
    };
}

MainActivity.java

package com.example.voice;

import android.support.v7.app.ActionBarActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.example.voice.VoiceBean.WS;
import com.google.gson.Gson;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.ui.RecognizerDialogListener;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
    private VoiceUtils voiceUtils;
    private StringBuffer stringBuffer;
    private ListView list;
    ArrayList<Conversation> conversations;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list = (ListView) findViewById(R.id.list);
        stringBuffer = new StringBuffer();
        voiceUtils = new VoiceUtils(this);
        conversations = new ArrayList<Conversation>();
    }

    // 步骤一
    public void start(View v) {
        voiceUtils.listen(new MyRecognizerDialogListener());
    }

    class MyRecognizerDialogListener implements RecognizerDialogListener {

        @Override
        public void onError(SpeechError arg0) {
            // TODO Auto-generated method stub

        }
        /*
         * isLast-------是否是最后一句 (non-Javadoc)
         */

        @Override
        public void onResult(RecognizerResult result, boolean isLast) {
            // TODO Auto-generated method stub
            // 打印出来的是json格式,需要解析
            System.out.println(result.getResultString());
            // 只能获取一句话,如果是一段话,需要把句与句之间拼接起来
            String word = processedData(result.getResultString());
            System.out.println(word);
            stringBuffer.append(word);
            if (isLast) {
                String question = stringBuffer.toString();
                // 我们说的话打印出来
                // System.out.println(stringBuffer.toString());
                // 清空之前的话,最简单的方法是新建,然后之前的就回收起来。
                stringBuffer = new StringBuffer();
                // 创建问题数据
                Conversation asker = new Conversation(question, true, -1);
                conversations.add(asker);
                // 更新ListView
                if (list.getAdapter() == null) {

                    list.setAdapter(new Myadapter());
                } else {
                    ((BaseAdapter) list.getAdapter()).notifyDataSetChanged();
                }
                String answerWord = "听不懂的说";
                int imgId = -1;
                // 更新回答数据
                if (question.contains("你好")) {
                    answerWord = "你也好";
                } else if (question.contains("美女")) {
                    Random random = new Random();
                    int newxInt = random.nextInt(Resource.imgIds.length);
                    answerWord = Resource.words[newxInt];
                    imgId = Resource.imgIds[newxInt];
                }
                Conversation answer = new Conversation(answerWord, false, imgId);
                conversations.add(answer);
                ((BaseAdapter) list.getAdapter()).notifyDataSetChanged();
                // 回答内容读出来
                voiceUtils.speak(answerWord);
                // 自动滑到最后一个条目
                list.setSelection(conversations.size());
            }

        }
    }

    class Myadapter extends BaseAdapter {

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = View.inflate(getApplicationContext(), R.layout.item, null);
            TextView tv_asker_right = (TextView) view.findViewById(R.id.tv_asker_right);
            LinearLayout ll_answer_left = (LinearLayout) view.findViewById(R.id.ll_answer_left);
            TextView tv_answer_left = (TextView) view.findViewById(R.id.tv_answer_left);
            ImageView iv_answer_left = (ImageView) view.findViewById(R.id.iv_answer_left);
            // 根据数据判断控件的显示
            Conversation conversation = conversations.get(position);
            if (conversation.isAsker) {// 问题
                tv_asker_right.setVisibility(View.VISIBLE);
                ll_answer_left.setVisibility(View.GONE);
                tv_answer_left.setText(conversation.word);
            } else {// 回答
                tv_asker_right.setVisibility(View.GONE);
                ll_answer_left.setVisibility(View.VISIBLE);
                if (conversation.imgId == -1) {// 是否有图片
                    iv_answer_left.setVisibility(View.GONE);
                } else {
                    iv_answer_left.setVisibility(View.VISIBLE);
                    iv_answer_left.setBackgroundResource(conversation.imgId);
                }
                tv_answer_left.setText(conversation.word);
            }
            return view;
        }

    }

    private String processedData(String string) {
        // TODO Auto-generated method stub
        Gson gson = new Gson();
        VoiceBean voiceBean = gson.fromJson(string, VoiceBean.class);
        // 对ws进行遍历
        stringBuffer = new StringBuffer();
        List<WS> ws = voiceBean.ws;
        for (int i = 0; i < ws.size(); i++) {
            // 获取的仅仅是一个字符,还需要拼接起来
            stringBuffer.append(ws.get(i).cw.get(0).w);
        }
        return stringBuffer.toString();
    }
}

 

posted @ 2016-06-07 15:18  沉默的羊癫疯  阅读(437)  评论(0编辑  收藏  举报