适配与第三方集成环境

屏幕适配

  1. 原型图和设计图

    1. 800*480 —> 向下兼容
    2. 1280*720 —> 向上兼容
  2. 图片适配:

    1. 根据屏幕的分辨率,选择drawable-xxxxx
    2. 图片的名称必须一致
  3. 布局的适配:

    1. layout-xxx, xxxx 是 高x宽(大乘小)如:layout-480x320
    2. 布局文件名称一致
  4. 尺寸的适配:

    1. px: pexl 像素
    2. dip/dp: denisity-independent pexl 自主密度的像素
    3. ppi: pexl per inch 每英寸有多少个像素点 > 300
    4. dpi: dots per inch 每英寸可打印的点

    5. ppi的计算:

          ppi = 开根(宽的平方 + 高的平方) / inch
      
          ppi = 开根(480^2 + 320^2) / 3.5   = 164
      
    6. dpi: 480*320 3.5 1dp = 1px dpi : 160
    7. 公式 : px = dp * (dpi / 160)

      1. dp = px / (dpi / 160);px自己想要的像素
      2. 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;
  1. 代码的适配(权重):

举个例子:

//最外侧的容器

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);

版本适配

  1. 通过判断版本去写代码
  2. 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. 搜索:科大讯飞语音云

使用:
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的集成和使用,具体的还需要多多研究。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值