android开发分享Android视频悬浮窗口实现的示例代码

前言本文例子实现了点击显示悬浮窗口,同时窗口可播放视频,拖动位置,点击关闭及返回 app 页面,通过例子来讲述悬浮窗口实现原理及细节处理,效果图如下所示:悬浮窗口.gif原理windowmanager

前言

android开发分享Android视频悬浮窗口实现的示例代码例子实现了点击显示悬浮窗口,同时窗口可播放视频,拖动位置,点击关闭及返回 app 页面,通过例子来讲述悬浮窗口实现原理及细节处理,效果图如下所示:

Android视频悬浮窗口实现的示例代码

悬浮窗口.gif

原理

 windowmanagerview 视图进行添加、移除、更新处理;

windowmanager.layoutparams 对窗口参数进行一系列设置。

实现

首先,需要添加相对应悬浮窗权限:

  <uses-permission android:name="android.permission.system_alert_window" />

activity 页面中,需要判断悬浮窗权限是否获取,如果未曾获取,需要跳转系统页,进行对应的授权操作:

  public boolean requestoverlaypermission() {    if (build.version.sdk_int >= build.version_codes.m) {      if (!settings.candrawoverlays(this)) {        intent intent = new intent(settings.action_manage_overlay_permission, uri.parse("package:" + getpackagename()));        startactivityforresult(intent, request_overlay_code);        return true;      } else {        return false;      }    }    return false;  }

获取权限后,我们可以首先初始化我们要显示的视图,并且设置相对应的事件,这里我们采用了 videoview 进行简单的视频播放,并且设置悬浮窗关闭及返回前台的操作:

  private view initfloatview() {    view view = view.inflate(this, r.layout.view_floating_window, null);    // 设置视频封面    final imageview mthumb = (imageview) view.findviewbyid(r.id.thumb_floating_view);    glide.with(this).load(r.drawable.thumb).into(mthumb);    // 悬浮窗关闭    view.findviewbyid(r.id.close_floating_view).setonclicklistener(new view.onclicklistener() {      @override      public void onclick(view v) {        mfloatingwindow.dismiss();      }    });    // 返回前台页面    view.findviewbyid(r.id.back_floating_view).setonclicklistener(new view.onclicklistener() {      @override      public void onclick(view v) {        mfloatingwindow.settopapp(floatingwindowactivity.this);      }    });    final videoview videoview = view.findviewbyid(r.id.video_view);    //视频内容设置   videoview.setvideopath("https://stream7.iqilu.com/10339/article/202002/18/2fca1c77730e54c7b500573c2437003f.mp4");    // 视频准备完毕,隐藏正在加载封面,显示视频    videoview.setonpreparedlistener(new mediaplayer.onpreparedlistener() {      @override      public void onprepared(mediaplayer mp) {        mthumb.setvisibility(view.gone);      }    });    // 循环播放    videoview.setoncompletionlistener(new mediaplayer.oncompletionlistener() {      @override      public void oncompletion(mediaplayer mp) {        videoview.start();      }    });    // 开始播放视频    videoview.start();    return view;  }

通过获取窗口管理 windowmanager ,设置悬浮窗口参数 windowmanager.layoutparams 后,就可以通过 windowmanageraddview 方法,生成对应视图的悬浮窗口:

  public void showfloatingwindowview(context context, view view) {    // 悬浮窗显示视图    mshowview = view;    // 获取系统窗口管理服务    mwindowmanager = (windowmanager) context.getsystemservice(context.window_service);    // 悬浮窗口参数设置及返回    mfloatparams = getparams();    // 设置窗口触摸移动事件    mshowview.setontouchlistener(new floatviewmovelistener());    // 悬浮窗生成    mwindowmanager.addview(mshowview, mfloatparams);  }

windowmanager.layoutparams 参数设置,主要设置悬浮窗口类型为 windowmanager.layoutparams.type_application_overlay

  private windowmanager.layoutparams getparams() {    windowmanager.layoutparams layoutparams = new windowmanager.layoutparams();    //设置悬浮窗口类型    if (build.version.sdk_int >= build.version_codes.o) {      layoutparams.type = windowmanager.layoutparams.type_application_overlay;    } else {      layoutparams.type = windowmanager.layoutparams.type_system_alert;    }    //设置悬浮窗口属性    layoutparams.flags = windowmanager.layoutparams.flag_not_focusable        | windowmanager.layoutparams.flag_not_touch_modal        | windowmanager.layoutparams.flag_layout_in_screen        | windowmanager.layoutparams.flag_layout_inset_decor        | windowmanager.layoutparams.flag_watch_outside_touch;    //设置悬浮窗口透明    layoutparams.format = pixelformat.translucent;    //设置悬浮窗口长宽数据    layoutparams.width = 600;    layoutparams.height = 340;    //设置悬浮窗显示位置    layoutparams.gravity = gravity.start | gravity.top;    layoutparams.x = 100;    layoutparams.y = 100;    return layoutparams;  }

窗口触摸移动事件,主要通过获取触摸位置,通过 windowmanagerupdateviewlayout 方法设置悬浮窗口的参数,进行窗口视图位置更新:

  private class floatviewmovelistener implements view.ontouchlistener {      //开始触控的坐标,移动时的坐标(相对于屏幕左上角的坐标)    private int mtouchstartx;    private int mtouchstarty;    //开始时的坐标和结束时的坐标(相对于自身控件的坐标)    private int mstartx, mstarty;    //判断悬浮窗口是否移动,这里做个标记,防止移动后松手触发了点击事件    private boolean ismove;      @override    public boolean ontouch(view view, motionevent motionevent) {      int action = motionevent.getaction();      int x = (int) motionevent.getx();      int y = (int) motionevent.gety();      switch (action) {        case motionevent.action_down:          ismove = false;          mtouchstartx = (int) motionevent.getrawx();          mtouchstarty = (int) motionevent.getrawy();          mstartx = x;          mstarty = y;          break;        case motionevent.action_move:          int mtouchcurrentx = (int) motionevent.getrawx();          int mtouchcurrenty = (int) motionevent.getrawy();          mfloatparams.x += mtouchcurrentx - mtouchstartx;          mfloatparams.y += mtouchcurrenty - mtouchstarty;          mwindowmanager.updateviewlayout(mshowview, mfloatparams);          mtouchstartx = mtouchcurrentx;          mtouchstarty = mtouchcurrenty;          float deltax = x - mstartx;          float deltay = y - mstarty;          if (math.abs(deltax) >= 5 || math.abs(deltay) >= 5) {            ismove = true;          }          break;        case motionevent.action_up:          break;        default:          break;      }      //如果是移动事件不触发onclick事件,防止移动的时候一放手形成点击事件      return ismove;    }  }

关闭悬浮窗,调用 windowmanagerremoveview 方法即可:

  public void dismiss() {    if (mwindowmanager != null && mshowview != null) {      mwindowmanager.removeview(mshowview);    }  }

悬浮窗点击返回前台方法:

  public void settopapp(context context) {    //获取activitymanager    activitymanager activitymanager = (activitymanager) context.getsystemservice(context.activity_service);    //获得当前运行的task(任务)    list<activitymanager.runningtaskinfo> taskinfolist = null;    if (activitymanager != null) {      taskinfolist = activitymanager.getrunningtasks(100);    }    if (taskinfolist != null) {      for (activitymanager.runningtaskinfo taskinfo : taskinfolist) {        //找到本应用的 task,并将它切换到前台        if (taskinfo.topactivity != null && taskinfo.topactivity.getpackagename().equals(context.getpackagename())) {          activitymanager.movetasktofront(taskinfo.id, 0);          break;        }      }    }  }

关于悬浮窗的一些基本操作到这里就基本结束了,具体的布局内容及操作,欢迎查看具体的源码实现: github开发记录

到此这篇关于android视频悬浮窗口实现的示例代码的文章就介绍到这了,更多相关android视频悬浮窗口 内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/898332.html

(0)
上一篇 2021年10月22日
下一篇 2021年10月22日

精彩推荐