屏幕适配和第三方集成科大讯飞语音
2016-09-05 20:48
513 查看
屏幕适配
原型图和设计图800*480 —> 向下兼容
1280*720 —> 向上兼容
图片适配:
根据屏幕的分辨率,选择drawable-xxxxx
图片的名称必须一致
布局的适配:
layout-xxx, xxxx 是 高x宽(大乘小)如:layout-480x320
布局文件名称一致
尺寸的适配:
px: pexl 像素
dip/dp: denisity-independent pexl 自主密度的像素
ppi: pexl per inch 每英寸有多少个像素点 > 300
dpi: dots per inch 每英寸可打印的点
ppi的计算:
ppi = 开根(宽的平方 + 高的平方) / inch ppi = 开根(480^2 + 320^2) / 3.5 = 164
dpi: 480*320 3.5 1dp = 1px dpi : 160
公式 : px = dp * (dpi / 160)
dp = px / (dpi / 160);px自己想要的像素
dpi值 ,自己查阅(文档)
ldpi: 320x240
dp = 120 /(120/160) = 160dp
mdpi: 480x320
dp = 160 / ( 160 / 160) = 160dp
hdpi: 800x480
dp = 240 / (240/160) = 160dp
xhdpi: 1280x720
dp = 360 /(320/160) = 180dp
A set of six generalized densities:
ldpi (low) ~120dpi mdpi (medium) ~160dpi hdpi (high) ~240dpi xhdpi (extra-high) ~320dpi xxhdpi (extra-extra-high) ~480dpi xxxhdpi (extra-extra-extra-high) ~640dpi 8. denisity : 像素密度(缩放比) denistity = px / dp; 1. dp = px / denistity;
通过代码获取手机相对应得像素,密度手机屏幕高度等相关信息:
DisplayMetris metrics=getResources().getDisplayMetrics(); float density=metrics.density; float densityDpi=metrics.densityDpi;
代码的适配(权重):
举个例子:
//最外侧的容器 LinearLayout container=new LinearLayout(this); container.setOrientation(LinearLayout.VERTICAL); LayoutParams params=new LayoutParams(LayoutParams.MATH_PARENT,LayoutParams.MATH_PARENT); LinearLayout topLayout=new LinearLayout(this); topLayout.setBackColor(Color.RED); params.weight=1; container.addView(topLayout,params); LinearLayout buttomLayout=new LinearLayout(this); buttomLayout.setBackColor(Color.RED); params.weight=1; container.addView(buttomLayout,params);
版本适配
通过判断版本去写代码android.jar它是在手机环境中的,不是在apk中
例如:
AsyncTask<void,void,void> task=new AsyncTask<void,void,void>(){ protected void doInBackgroup(void...params){ return null; } }; if(Build.VERSION.SDK_INT<Build.VERSION_CODES.HONEYCOMB){ //3.0之前是多线程的 task.execute(); }else{ //3.0之后是单线程队列的 if(executor==null){//线程池不为空,先定义出来 executor=Executors.newFixedThreadPool(3);//只开三个线程 } //3.0之后是单线程队列的 task.executeOnExecutor(executor); }
科大讯飞语音
听 :说 :
搜索:科大讯飞语音云
使用:
1. 注册账号
2. 创建应用
3. 使用服务
4. sdk下载
5. 集成
下面通过一个小案例来了解它的使用:语音机器人
通过科大讯飞文档,先集成使用环境,抽出一个听说的工具类 public class SpeekListenUtils { private Context mContext; public SpeekListenUtils(Context context) { this.mContext = context; // 请勿在“=”与 appid 之间添加任务空字符或者转义符 SpeechUtility.createUtility(context, SpeechConstant.APPID + "=57ab2dcc");//57ab2dcc为自己应用申请的appkey } //听的功能 public void listen(RecognizerDialogListener mRecognizerDialogListener) { // 1.创建RecognizerDialog对象 RecognizerDialog mDialog = new RecognizerDialog(mContext, null); // 2.设置accent、language等参数 mDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); mDialog.setParameter(SpeechConstant.ACCENT, "mandarin"); // 若要将UI控件用于语义理解,必须添加以下参数设置,设置之后onResult回调返回将是语义理解 //结果 // // mDialog.setParameter("asr_sch", "1"); // // mDialog.setParameter("nlp_version", "2.0"); // 3.设置回调接口 mDialog.setListener(mRecognizerDialogListener); // 4.显示dialog,接收语音输入 mDialog.show(); } //说的功能 public void speak(String text,SynthesizerListener mSynthesizerListener) { // 1.创建SpeechSynthesizer 对象, 第二个参数:本地合成时传InitListener SpeechSynthesizer mTts= SpeechSynthesizer.createSynthesizer(mContext, null); // //2.合成参数设置,详见《MSC Reference Manual》SpeechSynthesizer 类 // //设置发音人(更多在线发音人,用户可参见 附录13.2 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 卡权限 //仅支持保存为 pcm 和 wav // 格式,如果不需要保存合成音频,注释该行代码 mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,"./sdcard/iflytek.pcm"); //3.开始合成 mTts.startSpeaking(text, mSynthesizerListener); } }
现在先来看看语音机器人的实际效果图:问时:
————-
机器答时:
———–
在集成的sdk环境中,在听的时候会自动弹出一个透明对话框,这个已经封装好了如上图。我们自要对着屏幕说就可以啦。现在来看看:
先初始化布局,这个布局分为一个按钮,一个listView
<RelativeLayout 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" tools:context="com.cca.speekrobot.MainActivity" > <RelativeLayout android:id="@+id/bottom_speak" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="@drawable/bottom_bar" > <Button android:id="@+id/btn_speak_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/btn_voice_search_normal" android:textSize="25dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:gravity="center" android:onClick="clickListen" android:text="开始说话" /> </RelativeLayout> <ListView android:id="@+id/list_speak" android:layout_marginTop="5dp" android:layout_width="match_parent" android:cacheColorHint="@android:color/transparent" android:fadingEdge="none" android:layout_above="@id/bottom_speak" android:dividerHeight="0dp" android:listSelector="@android:color/transparent" android:layout_height="match_parent"> </ListView> </RelativeLayout>
初始化数据initData();
private void initData() { SpeekListenUtils utils=new SpeekListenUtils(this); ListView mList=(ListView) findViewById(R.id.list_speak); //设置数据 MyListAdapter adapter=new MyListAdapter(); mList.setAdapter(adapter); }
给按钮设置点击事件
//点击按钮,开始说语音让机器人听 public void clickListen(View view){ utils.listen(new MyRecognizerDialogListener()); }
完成听语音的监听和数据的获取:
private class MyRecognizerDialogListener implements RecognizerDialogListener{ @Override public void onError(SpeechError arg0) { } @Override public void onResult(RecognizerResult arg0, boolean isLast) { String result=arg0.getResultString(); Log.i(TAG, "---"+result); //解析json Gson json=new Gson(); ListDataBean bean=json.fromJson(result, ListDataBean.class); content += getResult(bean); //返回听到的文字content初始化为空字符串 //判断是否是最后一次 if(isLast){ //最后一次、问的话content------>convert ConvertBean ask=new ConvertBean(); ask.type=0; ask.text=content; if(mDatas==null){ mDatas=new LinkedList<ConvertBean>(); } mDatas.add(ask); //清空content content=""; //UI刷新 adapter.notifyDataSetChanged(); //回答 String text=ask.text; ConvertBean answer=null; Random adm=new Random(); int textSize=RobotRes.resText.length; int icomSize=RobotRes.resIcon.length; if(text.contains("美女")){//这里可以做很多判断 //bean answer =new ConvertBean(); answer.type=1; answer.img=RobotRes.resIcon[adm.nextInt(icomSize)];//随机返回 answer.text=RobotRes.resText[adm.nextInt(textSize)];//随机返回 }else{ answer =new ConvertBean(); answer.type=1; answer.img=-1; answer.text="不好意思,没听懂,请再说一遍!"; } //说出来 utils.speak(answer.text, null); mDatas.add(answer); //UI刷新 adapter.notifyDataSetChanged(); //滑动到下面可见 mList.setSelection(adapter.getCount()); } } } //获取数据 public String getResult(ListDataBean bean) { List<Wsbean> wsbean=bean.ws; StringBuffer sb=new StringBuffer(); for(Wsbean ws:wsbean){ List<Cwbean> cwbean=ws.cw; for(Cwbean cw:cwbean){ sb.append(cw.w); } } return sb.toString(); }
给listView设置适配器:
//适配器 class MyListAdapter extends BaseAdapter{ @Override public int getCount() { if(mDatas!=null){return mDatas.size();} return 0; } @Override public Object getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; //复用历史的convertview if(convertView==null){ convertView=View.inflate(getApplicationContext(), R.layout.list_item, null); holder=new ViewHolder(); holder.mAskLinLayout=convertView.findViewById(R.id.ask_container); holder.mAnswerRelLayout=convertView.findViewById(R.id.answer_container); holder.asktext=(TextView) convertView.findViewById(R.id.ask_text); holder.answertext=(TextView) convertView.findViewById(R.id.answer_text); holder.answerimg=(ImageView) convertView.findViewById(R.id.answer_img); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } //设置数据 ConvertBean data=mDatas.get(position); if(data.type==0){ //问 holder.mAskLinLayout.setVisibility(View.VISIBLE); holder.mAnswerRelLayout.setVisibility(View.GONE); holder.asktext.setText(data.text); }else{ //答 holder.mAskLinLayout.setVisibility(View.GONE); holder.mAnswerRelLayout.setVisibility(View.VISIBLE); holder.answertext.setText(data.text); if(data.img!=-1){ holder.answerimg.setImageResource(data.img); } } return convertView; } } class ViewHolder{ View mAskLinLayout; View mAnswerRelLayout; TextView asktext; TextView answertext; ImageView answerimg; }
在完成之前先创建问答在listView显示的item布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- 问--- 右侧 --> <RelativeLayout android:id="@+id/ask_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" > <TextView android:id="@+id/ask_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:background="@drawable/asker_bubble" android:textColor="#000000" android:gravity="center" android:text="sdfghjkdshdeSD卡万能fghj" /> </RelativeLayout> <!-- 答--- 左侧 --> <LinearLayout android:id="@+id/answer_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:orientation="vertical" > <TextView android:id="@+id/answer_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/answer_bubble" android:gravity="center" android:textColor="#000000" android:text="sdfghjkdshdeSD卡万能fghj" /> <ImageView android:id="@+id/answer_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/ic_launcher" /> </LinearLayout> </LinearLayout>
下面是自己创建的资源文件,图片放在drawable-hdpi中
public class RobotRes { public static int[] resIcon=new int[]{ R.drawable.p1,R.drawable.p2, R.drawable.p3,R.drawable.p4, R.drawable.p5,R.drawable.p6, R.drawable.p7,R.drawable.p8, R.drawable.p9,R.drawable.p10, }; public static String[] resText=new String[]{ "专业办证300年","天王盖地虎", "屌丝,朝前看吧","色狼,你的最爱", "我爱你","看见你死而无憾了", "世上有你相伴最好" }; }
存储数据的javabean:
public class ConvertBean { String text; int img=-1; int type=0;//0位问 ,1 为答 }
把获得的数据解析的javabean:
public class ListDataBean { public int bg; public int ed; public boolean ls; public int sn; public List<Wsbean> ws; class Wsbean{ public int bg; public List<Cwbean> cw; } class Cwbean{ public double sc; public String w; } }
到这里,语音机器人就简单完成了,这里只是简单介绍了语音sdk的集成和使用,具体的还需要多多研究。
相关文章推荐
- Android开发集成科大讯飞语音识别+语音合成功能
- 智能聊天机器人的实现(语音引入第三方科大讯飞)
- 有关集成科大讯飞sdk的语音(二)不带语音的界面
- Android 科大讯飞语音集成,文字转语音
- android studio 集成科大讯飞语音合成以及语音评测
- 有关集成科大讯飞sdk的语音(三)语音合成
- AndroidStudio集成科大讯飞语音SDK
- 在应用中集成科大讯飞的语音识别技术
- Android开发集成科大讯飞语音识别+语音合成功能
- Android——科大讯飞语音集成
- android集成科大讯飞语音听写和语音合成
- AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能
- AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能
- Android科大讯飞语音集成,非常详细的使用讲解
- Android开发集成科大讯飞语音识别+语音合成功能
- 科大讯飞语音集成,非常详细的使用讲解
- 适配与第三方集成环境
- 科大讯飞语音集成,非常详细的使用讲解
- 科大讯飞语音集成,使用讲解
- 第三方科大讯飞语音交互