郭霖大神的文章:http://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650235949&idx=1&sn=0f7eded67f834d38b02f8872768cb68a&scene=0#wechat_redirect

今天周二,又该跟大家分享由我执笔的文章了。从之前我写的deep links、通知栏微技巧这两篇文章中,大家应该能明显体会出什么叫短小精炼,但又很有技术价值的文章。后面我还会坚持分享这种类型的文章,尽量让大家十分钟内就可以读完,并且还能有所收获。


在Android上创建系统悬浮窗并不是什么新鲜技术,我的人生第一篇博客就是写的关于如何实现类似于360手机卫士悬浮窗的功能,大家有兴趣的可以到 http://guolin.tech 去翻翻历史。不过如果你将项目的targetSdkVersion指定成23或者更高,你会发现之前创建悬浮窗的方式在Android 6.0系统上是无法运行的。不信的话我们就来试试。

首先建立一个非常非常简单的自定义View:

public class FloatView extends Button {    
   public FloatView(Context context) {
       super(context);
       setBackgroundResource(R.drawable.logo);
   }
}

然后在程序中调用如下代码就可以创建出系统悬浮窗了:

public void showFloatView() {
   WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
   FloatView floatView = new FloatView(getApplicationContext());
   WindowManager.LayoutParams params = new WindowManager.LayoutParams();
   params.type = WindowManager.LayoutParams.TYPE_PHONE;
   params.format = PixelFormat.RGBA_8888;
   params.gravity = Gravity.LEFT | Gravity.TOP;
   params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
   params.width = 150;
   params.height = 150;
   params.x = 0;
   params.y = 0;
   windowManager.addView(floatView, params);
}

上面的代码简单易懂,就不再进行解释了,如果对这部分代码还不理解的朋友请去参考我的历史第一篇博文好好学习一下。

最后还需要在AndroidManifest.xml中添加一个权限:

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

没错,就是这么简单,现在这段代码就已经可以成功创建出一个系统悬浮窗了,不过是在Android 6.0系统之前。

如果我们在6.0系统中运行上述代码(注意targetSdkVersion要指定顾23),程序就会直接崩溃,错误日志如下图所示:

咦?报了个权限被拒绝的错误,可是我们已经在AndroidManifest.xml中申请权限了,并且SYSTEM_ALERT_WINDOW权限也不是危险权限,并不需要进行运行时权限申请。

那么为什么在6.0系统上就会崩溃呢,我们来查看一下官方文档的描述吧:

Note: If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with action ACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by calling Settings.canDrawOverlays().

能够熟练阅读各类英文文档也是一门非常重要的技能。上面的描述大概意思就是说,如果我们的targetSdkVersion指定成了23或者更高,在使用SYSTEM_ALERT_WINDOW权限时,需要先调用Settings.canDrawOverlays()来判断一下是否允许创建悬浮窗,如果允许的话就可以创建了,不允许的话还要发送一个action值为ACTION_MANAGE_OVERLAY_PERMISSION的Intent来让用户同意创建悬浮窗。

针对文档的描述,我们需要将代码改成下面这个样子:

public void buttonClick(View view) {
   if (Build.VERSION.SDK_INT >= 23) {
           if (Settings.canDrawOverlays(context)) {
           showFloatView();
       } else {
           Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
           startActivity(intent);
       }
   } else {
       showFloatView();
   }
}

首先最外层先判断当前的系统版本,如果低于6.0的话那就直接创建悬浮窗就可以了。当系统是6.0或者更高的时候,我们就使用刚才文档中描述的流程来进行逻辑实现,现在运行一下代码,效果如下图所示:

可以看到,当第一次创建悬浮窗的时候,会先跳转到一个系统设置界面,在这里我们选择允许当前程序创建系统悬浮窗,然后下一次再点击按钮时就能成功创建出系统悬浮窗了。

教你如何在Android 6.0上创建系统悬浮窗的更多相关文章

  1. 【译】如何在 Android 5.0 上获取 SD卡 的读写权限

    因为最近项目需要,涉及到 SD卡 的读写操作,然而申请 <!-- 读写权限 --> <uses-permission android:name="android.permi ...

  2. 教你如何在 Android 使用多线程下载文件

    # 教你如何在 Android 使用多线程下载文件 前言 在 Android 日常开发中,我们会经常遇到下载文件需求,这里我们也可以用系统自带的 api DownloadManager 来解决这个问题 ...

  3. Step by Step!教你如何在k3s集群上使用Traefik 2.x

    本文来自边缘计算k3s社区 作者简介 Cello Spring,瑞士人.从电子起步,拥有电子工程学位.尔后开始关注计算机领域,在软件开发领域拥有多年的工作经验. Traefik是一个十分可靠的云原生动 ...

  4. Android Api 27 在 Android 8.0 上出现 Only fullscreen opaque activities can request orientation 的解决情况

    刚上班,没有业务开发,对 App 的 Api 由 26 升级到了 27, 结果在 Android 8.0 的设备上会出现 crash . Log 如下: java java.lang.IllegalS ...

  5. visual studio 2017 中默认无法开发 Android 8.0 及以上系统的解决方案

    一般默认比较旧有两个原因,系统版本过旧,Visual Studio 版本过旧. 第一步,将windows 更新到最新版,必须是windows 10 并且更新到最新. 第二步,将visual studi ...

  6. Android 7.0以上版本 系统解决拍照的问题 exposed beyond app through ClipData.Item.getUri()

    解决方案1: android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg e ...

  7. Android 5.0以上获取系统运行进程信息

    在Android 5.0以上系统,调用getRunningAppProcesses 方法返回的列表为空,这是因为谷歌考虑到安全原因,已经把这个方法移除掉了, 那以后要获取系统运行的后台进程这个方法用不 ...

  8. 如何在Linux的桌面上创建快捷方式或启动器

    如果在Linux桌面系统中你经常使用一个程序,你可能想去创建一个“桌面快捷方式”,以便于你在桌面只要点击一下快捷方式就可以启动它.虽然不少带有图形界面的程序会在安装时自动在桌面上创建快捷方式,还有一些 ...

  9. 如何在 Windows 和 Linux 上确定系统使用的是 MBR 分区还是 GPT 分区详细步骤!!!

    在 Windows 上检查系统使用的是 MBR 分区还是 GPT 分区 点击放大镜搜索输入disk 点击打开 进入之后,右键点击你想要检查分区方案的磁盘,在右键菜单里选择属性! 在属性窗口,切换到卷, ...

随机推荐

  1. JavaScript正则表达式学习笔记之一 - 理论基础

    自从年前得空写了两篇文章之后就开始忙了,这一忙就是2个月

  2. Checkbutton

    #tkinter之Checkbutton篇 #Checkbutton又称为多选按钮,可以表示两种状态,On和Off,可以设置回调函数,每当点击此按钮时回调函数被调用. 1.一个简单的Checkbutt ...

  3. org.apache.commons.lang3.tuple.Pair 作为更新参数,XML 中的 Sql 取不到值、报错

    项目用的 Mybatis,今天改一个需求,落地实现是批量更新,且只需要根据主键(id)来更新一个字段(name). 于是,没有犹豫,像下面这样设计了数据结构: 既然是批量更新,那外层肯定是 List ...

  4. ●BZOJ 2393 Cirno的完美算数教室

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2393 题解: 容斥原理,暴力搜索,剪枝...和 [Scoi2010 幸运数字] 一样的(只是 ...

  5. ●BZOJ 3879 SvT

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3879 题解: 后缀数组,单调栈,RMQ 其实类似 BZOJ 3238 [Ahoi2013]差 ...

  6. 凸包(BZOJ1069)

    顶点一定在凸包上,我们枚举对角线,观察到固定一个点后,随着另一个点的增加,剩下两个点的最优位置一定是单调的,于是就得到了一个优秀的O(n^2)做法. #include <cstdio> # ...

  7. Mybatis迷你版--QueryObjectFactory

    今天在看JDBC4.2新规范,然后无意之间就碰到了这个东西QueryObjectFactory, 市面上orm框架有很多,在这里我就不一一列举了.那么今天我来记录一下QueryObjectFactor ...

  8. django rest-framework 1.序列化 一

    上图为项目完整的目录结构 一.入门 需要先安装需要使用到包 pip install django pip install djangorestframework 先来创建一个新项目 django-ad ...

  9. .eslintrc 文件

    安装 建议采用全局安装方式 npm install -g eslint 初始化 如果你的项目还没有配置文件(.eslintrc)的话,可以通过指定–init参数来生成一个新的配置文件: `eslint ...

  10. chrome不支持embed标签解决方案

    <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv=&quo ...