美文网首页
Android视频悬浮窗

Android视频悬浮窗

作者: 玖玖君 | 来源:发表于2019-12-25 17:24 被阅读0次

这个悬浮窗是一个类似于微信通话的小屏视频框,利于Service开启和保持。悬浮是利用WindowManager实现

创建FloatingWindowService服务类
public class FloatingWindowService extends Service implements View.OnClickListener {

    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;
    private View display;
    private TextureView surfaceView;
    private EasyPlayerClient client;
    private boolean show=true;
    private int qiehuan=0;

    private long startTime=0;
    private long endTime=0;

    private boolean isclick=false;


    public FloatingWindowService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        layoutParams = new WindowManager.LayoutParams();

        // 设置图片格式,效果为背景透明
        layoutParams.format = PixelFormat.RGB_565;

        Log.i("悬浮窗", "Build.VERSION.SDK_INT" + Build.VERSION.SDK_INT);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            // android 8.0及以后使用
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            // android 8.0以前使用
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        //该flags描述的是窗口的模式,是否可以触摸,可以聚焦等
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        // 设置视频的播放窗口大小
        layoutParams.width = 400;
        layoutParams.height = 550;
        layoutParams.x = 700;
        layoutParams.y = 0;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (show) {
            showFloatingWindow();
        }
        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }

    @SuppressLint("NewApi")
    private void showFloatingWindow(){
        if (Settings.canDrawOverlays(this)) {
            LayoutInflater layoutInflater = LayoutInflater.from(this);
            display = layoutInflater.inflate(R.layout.little, null);
            surfaceView = display.findViewById(R.id.texture_view);
            client = new EasyPlayerClient(this, BuildConfig.KEY, surfaceView, null, null);
            final EditText et = new EditText(this);
            et.setHint("请输入RTMP地址");
            final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
            et.setText(sp.getString("url", "rtmp://111.198.38.150:10085/live/869496039536917_0001"));
            client.play("rtmp://111.198.38.150:10085/live/869496039536917_0001");
            windowManager.addView(display, layoutParams);
            display.setOnTouchListener(new FloatingOnTouchListener());
            display.setOnClickListener(new FloatingOnClickListener());
            show=false;
        }
    }

    @Override
    public void onClick(View v) {

    }


    //点击事件
    private class FloatingOnClickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            if (qiehuan % 2 == 0) {
                MainActivity.qiehuan();
                client.stop();
                client.play("rtmp://111.198.38.150:10085/live/863065035752780_0001");
            } else {
                MainActivity.qiehuan();
                client.stop();
                client.play("rtmp://111.198.38.150:10085/live/869496039536917_0001");
            }
            qiehuan++;
        }
    }


    // touch移动视频窗口 | 事件拦截
    private class FloatingOnTouchListener implements View.OnTouchListener {
        private int x;
        private int y;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();

                    isclick = false;//当按下的时候设置isclick为false

                    startTime = System.currentTimeMillis();
                    break;

                case MotionEvent.ACTION_MOVE:
                    isclick = true;//当按钮被移动的时候设置isclick为true
                    int nowX = (int) event.getRawX();
                    int nowY = (int) event.getRawY();
                    int movedX = nowX - x;
                    int movedY = nowY - y;
                    Log.d("悬浮窗", "movedX = " + movedX + ", movedY =" + movedY);
                    x = nowX;
                    y = nowY;
                    layoutParams.x = layoutParams.x + movedX;
                    layoutParams.y = layoutParams.y + movedY;
                    windowManager.updateViewLayout(view, layoutParams);
                    break;
                case MotionEvent.ACTION_UP:
                    endTime = System.currentTimeMillis();
                    //当从点击到弹起小于半秒的时候,则判断为点击,如果超过则不响应点击事件
                    if ((endTime - startTime) > 0.1 * 1000L) {
                        isclick = true;
                        Log.e("tag","拖动");
                    } else {
                        isclick = false;
                        Log.e("tag","点击");
                    }
                    System.out.println("执行顺序up");
                    break;
            }
            return isclick;
        }
    }

    @Override
    public void onDestroy() {
        // 移除浮动框
        if (windowManager != null) {
            windowManager.removeView(display);
        }
        super.onDestroy();
    }
}
别忘了在AndroidManifest.xml调用服务
Activity里开启服务(仅展示重要部分)
  //判断是否授权及开启服务
 @RequiresApi(api = Build.VERSION_CODES.M)
    public void startFloatingService() {
        if (ActivityUtil.isServiceWork(this, "com.demon.suspensionbox.FloatingService")) {//防止重复启动
            Toast.makeText(this, "已启动!", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(this, "当前无权限,请授权", Toast.LENGTH_SHORT).show();
            startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);
        } else {
            if (istui)
                startService(new Intent(MainActivity.this, FloatingWindowService.class));
        }
    }

 @SuppressLint("NewApi")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 判断获取权限是否成功
        if (requestCode == 0) {
            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
                startService(new Intent(MainActivity.this, FloatingWindowService.class));
            }
        }
    }


    //关闭服务
   @Override
      public void onDestroy() {
        stopService(new Intent(MainActivity.this, FloatingWindowService.class));
          super.onDestroy();
      }

至此,就实现了一个很biu特否的视频悬浮框,更多功能还在筹备中,敬请期待

文章很短,路还漫长,大家好,我是玖玖君,一个帅气与才华并存的男人,我们下期再见。

相关文章

  • Android视频悬浮窗

    这个悬浮窗是一个类似于微信通话的小屏视频框,利于Service开启和保持。悬浮是利用WindowManager实现...

  • Android 悬浮窗-开箱即用

    开箱即用的 Android 悬浮窗 开箱即用的 Android 悬浮窗 FloatWindowX 1. 需要权限 ...

  • Android悬浮窗权限适配

    转载请注明出处:Android悬浮窗权限适配 悬浮窗相信大家都不陌生,比如360手机卫士的加速球,视频应用的小窗,...

  • 关于android 悬浮窗和自启动的设置, 以及获取系统的信息

    关于android 悬浮窗和自启动的设置, 以及获取系统的信息 标签(空格分隔):Android 悬浮窗 对于是否...

  • Android权限适配(二)

    本文接 Android权限适配(一) 悬浮窗权限 悬浮窗权限同样属于上文中说到的特殊权限。 悬浮窗代码的设置 要使...

  • Android 悬浮窗实现

    Android悬浮窗实现中需要注意的两点是 1、Android 6.0之后的悬浮窗动态申请 2、Window 的y...

  • android 悬浮窗

    安卓悬浮窗的书写,我们分为几个步骤: 1.添加悬浮窗权限 2.书写悬浮窗代码,搭建悬浮窗布局 3.判断悬浮窗权限是...

  • Android 悬浮窗<下>

    上篇Android 悬浮窗<上>已经将Window、WindowManager做了一些简单介绍,并且将悬浮窗适配做...

  • Android7.1悬浮窗自动消失解决办法

    问题描述 日前在做一个悬浮窗需求悬浮窗,在Android 7.1模拟器上悬浮窗会显示几秒钟就自动消失。 问题分析 ...

  • Android监听悬浮框是否显示解决方案

    1.引言 项目中用到android悬浮窗,可是有些手机即使在悬浮窗权限授权了也无法弹出。因为项目中要对悬浮窗是否弹...

网友评论

      本文标题:Android视频悬浮窗

      本文链接:https://www.haomeiwen.com/subject/odococtx.html