您的位置:首页 > 其它

屏幕适配和第三方集成科大讯飞语音

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的集成和使用,具体的还需要多多研究。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  科大讯飞