带有android悬浮窗的语音识别语义理解demo

转载请注明优快云博文地址:http://blog.youkuaiyun.com/ls0609/article/details/77162417

在线听书demo:http://blog.youkuaiyun.com/ls0609/article/details/71519203
语音记账demo:http://blog.youkuaiyun.com/ls0609/article/details/72765789

android桌面悬浮窗实现比较简单,本篇以一个语音识别,语义理解的demo来演示如何实现android悬浮窗。

1.悬浮窗效果

桌面上待机的时候,悬浮窗吸附在边上

这里写图片描述

拖动远离屏幕边缘时图标变大,松开自动跑到屏幕边缘,距离屏幕左右边缘靠近哪边吸附哪边

这里写图片描述

点击悬浮图标时,启动录音

这里写图片描述

说完后可以点击左button,上传录音给服务器等待处理返回结果

这里写图片描述

服务器返回结果后自动跳转到应用界面,本例用的是在线听书,跳转到在线听书的界面

这里写图片描述

2.FloatViewIdle与FloatViewIdleService

1.FloatViewIdle
定义一个FloatViewIdle类,如下是该类的单例模式

public static synchronized FloatViewIdle getInstance(Context context)
{
        if(floatViewManager == null)
        {
            mContext = context.getApplicationContext();;
            winManager = (WindowManager) 
                                    mContext.getSystemService(Context.WINDOW_SERVICE);
            displayWidth = winManager.getDefaultDisplay().getWidth();
            displayHeight = winManager.getDefaultDisplay().getHeight();
            floatViewManager = new FloatViewIdle();
        }
        return floatViewManager;
}

利用winManager 的addview方法,把自定义的floatview添加到屏幕中,那么就会在任何界面显示该floatview,然后再屏蔽非待机界面隐藏floatview,这样就只有待机显示悬浮窗了。

定义两个自定义view,分别是FloatIconView和FloatRecordView,前者就是待机看到的小icon图标,后者是点击这个icon图标后展示的录音的那个界面。

下面来看下怎么定义的FloatIconView

class FloatIconView extends LinearLayout{

        private int mWidth;
        private int mHeight;
        private int preX;
        private int preY;
        private int x;
        private int y;
        public boolean isMove;
        public boolean isMoveToEdge;    
        private FloatViewIdle manager;
        public ImageView imgv_icon_left;
        public ImageView imgv_icon_center;
        public ImageView imgv_icon_right;
        public int mWidthSide;

        public FloatIconView(Context context) {
            super(context);

            View view = LayoutInflater.from(mContext).
                                       inflate(R.layout.layout_floatview_icon, this);
            LinearLayout layout_content = 
                              (LinearLayout)  view.findViewById(R.id.layout_content);
            imgv_icon_left = (ImageView) view.findViewById(R.id.imgv_icon_left);
            imgv_icon_center = (ImageView) view.findViewById(R.id.imgv_icon_center);
            imgv_icon_right = (ImageView) view.findViewById(R.id.imgv_icon_right);
            imgv_icon_left.setVisibility(View.GONE);
            imgv_icon_center.setVisibility(View.GONE);

            mWidth = layout_content.getWidth();
            mHeight = layout_content.getHeight();
            if((mWidth == 0)||(mHeight == 0))
            {
                int temp = DensityUtil.dip2px(mContext, icon_width);
                mHeight = temp;
                icon_width_side_temp = DensityUtil.dip2px(mContext, icon_width_side);
                mWidth = icon_width_side_temp;
            }
            manager = FloatViewIdle.getInstance(mContext);
            if(params != null)
            {
                params.x = displayWidth - icon_width_side_temp;
                params.y = displayHeight/2;
            }
        }

        public int getFloatViewWidth()
        {
            return mWidth;
        }
        public int getFloatViewHeight()
        {
            return mHeight;
        }

        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            switch(event.getAction())
            {
            case MotionEvent.ACTION_DOWN:
                 preX = (int)event.getRawX();
                 preY = (int)event.getRawY();
                 isMove = false;
                 if(params.width == icon_width_side_temp)
                     handler.sendMessage(handler.obtainMessage(
                                        MSG_UPDATE_FLOAT_VIEW_AFTER_CHANGED, 3, 0));
                 break;
            case MotionEvent.ACTION_UP:              
                 if(isMoveToEdge == true)
                 {
                     if(params.width == icon_width_side_temp)
                         handler.sendMessage(handler.obtainMessage(
                                        MSG_UPDATE_FLOAT_VIEW_AFTER_CHANGED, 3, 0));
                     handler.sendMessage(handler.obtainMessage(
                                                 MSG_FLOAT_VIEW_MOVE_TO_EDGE,this));                     
                 }
                 break;
            case MotionEvent.ACTION_MOVE:
                 x = (int)event.getRawX();
                 y = (int)event.getRawY();               
                 if(Math.abs(x-preX)>1||Math.abs(y-preY)>1)
                 {                   
                  isMoveToEdge = true;
                 }
                 if(Math.abs(x-preX)>5||Math.abs(y-preY)>5)
                     isMove = true;
                 if(params.width == icon_width_side_temp)
                     handler.sendMessage(handler.obtainMessage(
                                       MSG_UPDATE_FLOAT_VIEW_AFTER_CHANGED, 3, 0));
                 manager.move(this, x-preX, y-preY);
                 preX = x;
                 preY = y;
                 break;
            }
            return super.onTouchEvent(event);
        }
    }

通过layout文件生成一个FloatIconView,在onTouchEvent函数中当按下的时候,发送消息更新悬浮view,抬起即up事件时先更新悬浮view,然后再显示吸附到边上的动画。 当move的时候,判断每次位移至少5和像素则更新view位置,这样不断move不断更新就会形成连续的画面。

另一个FloatRecordView(录音的悬浮窗)道理相同,这

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值