Android 语音助手

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AmazingUU/article/details/54988974

效果图

VoiceAssisant



















注:效果图是用华为荣耀2平板录制的,不支持SIM卡,没有打电话和短信的效果。但是我是用三星S3测试的,可以正常实现打电话和发短信的功能。因为三星S3不知道为什么不能用Vysor将手机画面显示在电脑上,所以我只好用华为荣耀2平板录制了,敬请见谅。

项目地址

Github地址:Android-VoiceAssistant

简介、功能等说明Github的README.md里都写了,这里不做赘述。主要说说开发中遇到的问题

开发过程中遇到的问题

1.主界面是一个ListView和一个ImageView,ListView的item代码如下:

public class ListData {

    public static final int SEND = 1;      // 发送
    public static final int RECEIVER = 2;  // 接收
    private String content;
    // 标识,判断是左边,还是右边。
    private int flag;    
    private String time;

    public ListData(String content,int flag) {
        setContent(content);
        setFlag(flag);
    }

    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public int getFlag() {
        return flag;
    }
    public void setFlag(int flag) {
        this.flag = flag;
    }
}

这里item分成左边和右边,分别是SEND和RECEIVER,利用flag来区分。这样的话,我在写ListView的adapter的getView()时,一开始还是用正常的四步:
(1) 获取或创建viewholder
(2)获取当前item数据
(3)显示数据
(4)返回view
但是这样处理之后,发现不管是SEND还是RECIVER都会显示在ListView的左边。问题出现在下面这段代码:

//获取或创建viewholder
        ViewHolder holder=null;
        if (convertView==null){
            holder=new ViewHolder();
            if (lists.get(position).getFlag() == ListData.RECEIVER) {
                convertView=View.inflate(mContext,R.layout.leftitem,null);
                holder.content= (TextView) convertView.findViewById(R.id.tv);
        }
            if (lists.get(position).getFlag() == ListData.SEND) {           convertView=View.inflate(mContext,R.layout.rightitem,null);
                holder.content= (TextView) convertView.findViewById(R.id.tv);               
            convertView.setTag(holder);
        }else {
            holder= (ViewHolder) convertView.getTag();
        }

初始化View时,convertView为null,会创建ViewHolder,此时flag是RECEIVER ,然后被setTag()进convertView,那么的后面不会再次创建ViewHolder,直接从
convertView的getTag()得到,所以flag一直都是RECEIVER,所以才会都显示在左边。要加上几个判断,最后修改为:

public View getView(int position, View convertView, ViewGroup parent) {
        //获取或创建viewholder
        ViewHolder holder=null;
        if (convertView==null){//第一次肯定为RECEIVER
            holder=new ViewHolder();
            convertView=View.inflate(mContext,R.layout.leftitem,null);
            holder.content= (TextView) convertView.findViewById(R.id.tv);

            convertView.setTag(holder);
        }else {
            holder= (ViewHolder) convertView.getTag();
            if (lists.get(position).getFlag() == ListData.SEND){
                convertView=View.inflate(mContext,R.layout.rightitem,null);
                holder.content= (TextView) convertView.findViewById(R.id.tv);

                convertView.setTag(holder);
            }else {
                convertView=View.inflate(mContext,R.layout.leftitem,null);
                holder.content= (TextView) convertView.findViewById(R.id.tv);

                convertView.setTag(holder);
            }
        }

        //获取当前item数据
        ListData listData=lists.get(position);

        //显示数据
        if (listData.getFlag()==ListData.RECEIVER){
            holder.content.setText(listData.getContent());
        }else {
            holder.content.setText("\""+lists.get(position).getContent()+"\"");//如果是发送的信息,加上双引号
        }

        //返回view
        return convertView;
    }

2.本来我想用语音识别返回的数据解析成JSON数据,然后再根据关键字实现各个功能,但是不知道为什么,返回数据这种格式:

02-11 23:24:28.919 22613-22613/com.tulingdemo D/tag: origin_result=
                                                     {
                                                         "content": {
                                                             "item": [
                                                                 "给张三打电话"
                                                             ]
                                                         },
                                                         "result": {
                                                             "corpus_no": 6385871906810761080,
                                                             "err_no": 0,
                                                             "idx": -14,
                                                             "res_type": 3,
                                                             "sn": "8a6fb1d6-d6ab-48a6-935c-6f166e372b03"
                                                         }
                                                     }

并不是官网上说的这种格式:

{
    "raw_text": "给张三打电话",
    "parsed_text": "给张三打电话",
    "results": [
        {
            "domain": "telephone",
            "intent": "call",
            "object": {
                "name": "张三"
            }
        }
    ]
}

问题应该是我解析的问题,那我只好采用下面的方法来根据关键字实现各种功能了

//关键词"打电话"
            if (res.contains("打电话")){//res为语音识别出的String结果
                call();
                return;
            }

后面有时间还是会解析成JSON格式来处理。

3.在实现发短信功能时,短信的内容可能有关键词,那么就要判断一下是不是短信的内容

//如果是发送的短信内容,必须写在最前面,防止短信内容里面出现关键词
            if (isMessage){//isMessage初始化时为false
                sendContent(res);
                isMessage=false;
                return;
            }
            //关键词"发短信"
            if (res.contains("发短信")){
                sendToWho();//该方法里将isMessage置为true
                return;
            }

P.S.文章格式的实际效果为什么和我预览的效果不一样?

猜你喜欢

转载自blog.csdn.net/AmazingUU/article/details/54988974