悬浮窗是在系统上显示的内容,好像微信视频聊天时的小窗口一样,在退出软件后依然存在的一个窗口,本博客以窗口中放一个button组件为例,简单展示悬浮窗,其中包括了对Android 6.0以下、Android 6.0到Android 8.0、Android 8.0以上版本的处理,下面开始介绍实现方法:

1、MainActivity中的代码

public Button mFloatingButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化viewinitView();}//初始化viewprivate 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));}}@Overrideprotected 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));}}}@Overridepublic 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"><Buttonandroid: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;@Overridepublic 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@Overridepublic IBinder onBind(Intent intent) {Log.e("进入服务2", "进入服务2");return null;}@Overridepublic 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;@Overridepublic 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悬浮窗 源码下载

Android 悬浮窗全系统版本实现相关推荐

  1. Android悬浮窗适配全机型,包含8.0,小米魅族华为悬浮窗权限适配demo看这一篇就够了

    机型多杂,适配无法完全兼容,不如换种实现方式,性能比悬浮窗好,不需要权限,效果更好:https://blog.csdn.net/m0_38058826/article/details/10399339 ...

  2. Android悬浮窗原理解析(Window)[源码]

    悬浮窗,在大多数应用中还是很少见的,目前我们接触到的悬浮窗,差不多都是一些系统级的应用软件,例如:360安全卫士,腾讯手机管家等:在某些服务行业如金融,餐饮等,也会在应用中添加悬浮窗,例如:美团的偷红 ...

  3. Android悬浮窗的实现

    Android悬浮窗的实现 *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本文也发布于本人的知乎文章:https://zhuanlan.zhihu.com/p/39421112 ...

  4. android动态获取悬浮窗,Android 悬浮窗实现

    Android悬浮窗实现中需要注意的两点是 1.Android 6.0之后的悬浮窗动态申请 2.Window 的type属性在Android8.0前后的适配 public abstract class ...

  5. Android 悬浮窗语音识别功能开发详解

    笔者是一个普通不能再普通的程序员,本着出处兴趣,花时间研究了一下,想实现手机的悬浮窗语音识别功能,这样不影响自己其它操作的,语音识别技术是用百度云语音sdk,应该不难实现,很难实现就是核心语音识别技术 ...

  6. Android 悬浮窗功能的实现

    前言 我们大多数在两种情况下可以看到悬浮窗,一个是视频通话时的悬浮窗,另一个是360卫士的悬浮球,实现此功能的方式比较多,这里以视频通话悬浮窗中的需求为例.编码实现使用Kotlin.Java版本留言邮 ...

  7. Android展开悬浮窗功能,Android 悬浮窗 (附圆形菜单悬浮窗)

    序言 Android悬浮窗的实现,主要有四个步骤: 1. 声明及申请权限 2. 构建悬浮窗需要的控件 3. 将控件添加到WindowManager 4. 必要时更新WindowManager的布局 一 ...

  8. Android悬浮窗开启 适配所有机型(附源码)

    Android悬浮窗开启 适配所有机型(附源码) 1.开启悬浮窗权限 清单文件中添加: <uses-permission android:name="android.permissio ...

  9. Android 悬浮窗,绝对是目前相关悬浮窗开源库最完美的适配方案

    PerfectFloatWindow 项目地址:Alonsol/PerfectFloatWindow 简介: android 全局悬浮窗,目前已经适配华为,小米,vivo,oppo,一加,三星,魅族, ...

最新文章

  1. Mac 新建unix可执行文件
  2. ip_vs实现分析(2)
  3. GRPC在网页前端的使用
  4. 再次参加(第七届)商学院徒步戈壁挑战赛,赋词几首
  5. 一文了解“最好编程语言”PHP 必知的 16 个编程法则!
  6. js(javascript)中__proto__和prototype解析
  7. 在Microsoft Windows XP中使用NetMeeting
  8. 使用Gps获取经纬度
  9. cvtColor使用
  10. 三极管作为电流源时的公式计算
  11. eclipse SWT 中实现工程图标最小化到托盘,并只能右键托盘图标选择关闭
  12. Maya-Mixamo导出几何缓存错误
  13. krpano plugin interface
  14. QQ网页登陆密码加密方式农场、空间、WebQQ等通用
  15. Apache URL重定向指南
  16. 空间分析与应用实验报告实验一燕麦试验田选址
  17. socket读写返回值的处理
  18. UDA_TP阅读笔记
  19. 80后的麦当劳如何俘获年轻人的心
  20. 4.2. sysctl - configure kernel parameters at runtime

热门文章

  1. GuassDB数据库的GRANT REVOKE
  2. 完整分页器最骚的讲解(亲测)
  3. GB28181学习笔记6 解析invite命令
  4. C语言rand()函数产生随机数
  5. 新服务器有预装的系统吗,服务器自带操作系统吗
  6. 从Cloudflare事件,看DNS服务的重要性
  7. anaconda3/lib/python3.6/site-packages/torch/lib/libtorch_python.so: undefined symbol: PySlice_Unpack
  8. 变压器 线圈 绕紧绕松的影响
  9. bash: /usr/local/java/anaconda/anaconda3/bin/anaconda: /home/hadoop/anaconda3/bin/python: 解释器错误: 没有那
  10. 事务四大特性之——隔离性