Android实现悬浮窗全系统版本
程序员文章站
2022-06-06 23:46:22
悬浮窗是在系统上显示的内容,好像微信视频聊天时的小窗口一样,在退出软件后依然存在的一个窗口,本博客以窗口中放一个button组件为例,简单展示悬浮窗,其中包括了对android 6.0...
悬浮窗是在系统上显示的内容,好像微信视频聊天时的小窗口一样,在退出软件后依然存在的一个窗口,本博客以窗口中放一个button组件为例,简单展示悬浮窗,其中包括了对android 6.0以下、android 6.0到android 8.0、android 8.0以上版本的处理,下面开始介绍实现方法:
1、mainactivity中的代码
public button mfloatingbutton; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); //初始化view initview(); } //初始化view private void initview() { mfloatingbutton=(button) findviewbyid(r.id.floating_btn); mfloatingbutton.setonclicklistener(this); } public void startfloatingbuttonservice(view view) { log.e("测试流程", "测试流程"); if (floatingservice_button.isstarted) { log.e("测试流程2", "测试流程2"); return; } if (build.version.sdk_int >= build.version_codes.m) {//判断系统版本 if (!settings.candrawoverlays(this)) { toast.maketext(this, "当前无权限,请授权", toast.length_short); log.e("测试流程3", "测试流程3"); startactivityforresult(new intent(settings.action_manage_overlay_permission, uri.parse("package:" + getpackagename())), 0); } else { log.e("测试流程4", "测试流程4"); startservice(new intent(mainactivity.this, floatingservice_button.class)); } } else { startservice(new intent(mainactivity.this, floatingservice_button.class)); } } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { if (requestcode == 0) { if (!settings.candrawoverlays(this)) { log.e("测试流程5", "测试流程5"); toast.maketext(this, "授权失败", toast.length_short).show(); } else { log.e("测试流程6", "测试流程6"); toast.maketext(this, "授权成功", toast.length_short).show(); startservice(new intent(mainactivity.this, floatingservice_button.class)); } } } @override public void onclick(view v) { switch (v.getid()){ case r.id.floating_btn : startfloatingbuttonservice(v); break; } }
思路简单解释:点击弹出悬浮窗按钮时,获取版本并判断“build.version.sdk_int >= build.version_codes.m”如果系统版本在6.0以下这不需要请求权限,如果系统版本在6.0以上需要进行权限检测以及请求,获取权限后,弹出悬浮框
2、activity_main.xml代码
<?xml version="1.0" encoding="utf-8"?> <linearlayout 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" android:orientation="vertical" tools:context="com.example.jack_lin.suspendwindow.mainactivity"> <button android:id="@+id/floating_btn" style="@style/floatingbtn" android:text="@string/floating_btn" /> </linearlayout>
简单解释:xml中没什么特别东西,线性布局中放一个按钮
3、floatingservice_button的代码
public static boolean isstarted = false; private windowmanager windowmanager; private windowmanager.layoutparams layoutparams; private button button; @override public void oncreate() { super.oncreate(); log.e("进入服务1", "进入服务1"); isstarted = true; windowmanager = (windowmanager) getsystemservice(window_service); 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_phone; } layoutparams.format = pixelformat.rgba_8888; layoutparams.gravity = gravity.left | gravity.top; layoutparams.flags = windowmanager.layoutparams.flag_not_touch_modal | windowmanager.layoutparams.flag_not_focusable; layoutparams.width = 500; layoutparams.height = 100; layoutparams.x = 300; layoutparams.y = 300; } @nullable @override public ibinder onbind(intent intent) { log.e("进入服务2", "进入服务2"); return null; } @override public int onstartcommand(intent intent, int flags, int startid) { log.e("进入服务3", "进入服务3"); showfloatingwindow(); return super.onstartcommand(intent, flags, startid); } private void showfloatingwindow() { if (build.version.sdk_int >= build.version_codes.m) {//判断系统版本 if (settings.candrawoverlays(this)) { button = new button(getapplicationcontext()); button.settext("我是个button窗口"); button.setbackgroundcolor(color.blue); windowmanager.addview(button, layoutparams); button.setontouchlistener(new floatingontouchlistener()); } } else { button = new button(getapplicationcontext()); button.settext("我是个button窗口"); button.setbackgroundcolor(color.blue); windowmanager.addview(button, layoutparams); button.setontouchlistener(new floatingontouchlistener()); } } 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(); break; case motionevent.action_move: int nowx = (int) event.getrawx(); int nowy = (int) event.getrawy(); int movedx = nowx - x; int movedy = nowy - y; x = nowx; y = nowy; layoutparams.x = layoutparams.x + movedx; layoutparams.y = layoutparams.y + movedy; windowmanager.updateviewlayout(view, layoutparams); break; default: break; } return false; } }
思路简单解释:首先获取windowmanager服务,然后定义并设置在window上显示的layoutparams(此处需注意android 8.0以上版本中layoutparam里的type变量变为type_application_overlay与android 8.0以下版本layoutparam里的type变量type_phone不一样,需要通过判断系统版本进行区分),然后定义并设置在layoutparams上面显示的button按钮以及监听事件(此处的监听事件主要是悬浮窗口拖动的监听)最后将设置好的button与layoutparams添加入window中
4、androidmanifest.xml中权限添加
<uses-permission android:name="android.permission.system_alert_window" /> <uses-permission android:name="android.permission.internet" />
5、效果图
源码下载地址:android悬浮窗 源码下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。