Android 语音助手
效果图注:效果图是用华为荣耀2平板录制的,不支持SIM卡,没有打电话和短信的效果。但是我是用三星S3测试的,可以正常实现打电话和发短信的功能。因为三星S3不知道为什么不能用Vysor将手机画面显示在电脑上,所以我只好用华为荣耀2平板录制了,敬请见谅。项目地址Github地址:Android-VoiceAssistant
简介、功能等说明Github的README.md里都写了,这里不做赘述。主要说说开发中遇到的问题
开发过程中遇到的问题1.主界面是一个ListView和一个ImageView,ListView的item代码如下:
publicclassListData{publicstaticfinalintSEND=1;//发送publicstaticfinalintRECEIVER=2;//接收privateStringcontent;//标识,判断是左边,还是右边。privateintflag;privateStringtime;publicListData(Stringcontent,intflag){setContent(content);setFlag(flag);}publicStringgetContent(){returncontent;}publicvoidsetContent(Stringcontent){this.content=content;}publicintgetFlag(){returnflag;}publicvoidsetFlag(intflag){this.flag=flag;}}这里item分成左边和右边,分别是SEND和RECEIVER,利用flag来区分。这样的话,我在写ListView的adapter的getView()时,一开始还是用正常的四步:(1)获取或创建viewholder(2)获取当前item数据(3)显示数据(4)返回view但是这样处理之后,发现不管是SEND还是RECIVER都会显示在ListView的左边。问题出现在下面这段代码:
//获取或创建viewholderViewHolderholder=null;if(convertView==null){holder=newViewHolder();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,所以才会都显示在左边。要加上几个判断,最后修改为:
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){//获取或创建viewholderViewHolderholder=null;if(convertView==null){//第一次肯定为RECEIVERholder=newViewHolder();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数据ListDatalistData=lists.get(position);//显示数据if(listData.getFlag()==ListData.RECEIVER){holder.content.setText(listData.getContent());}else{holder.content.setText("""+lists.get(position).getContent()+""");//如果是发送的信息,加上双引号}//返回viewreturnconvertView;}2.本来我想用语音识别返回的数据解析成JSON数据,然后再根据关键字实现各个功能,但是不知道为什么,返回数据这种格式:
02-1123:24:28.91922613-22613/com.tulingdemoD/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初始化时为falsesendContent(res);isMessage=false;return;}//关键词"发短信"if(res.contains("发短信")){sendToWho();//该方法里将isMessage置为truereturn;}P.S.文章格式的实际效果为什么和我预览的效果不一样?