教你如何在Android 6.0上创建系统悬浮窗
郭霖大神的文章: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上创建系统悬浮窗的更多相关文章
- 【译】如何在 Android 5.0 上获取 SD卡 的读写权限
因为最近项目需要,涉及到 SD卡 的读写操作,然而申请 <!-- 读写权限 --> <uses-permission android:name="android.permi ...
- 教你如何在 Android 使用多线程下载文件
# 教你如何在 Android 使用多线程下载文件 前言 在 Android 日常开发中,我们会经常遇到下载文件需求,这里我们也可以用系统自带的 api DownloadManager 来解决这个问题 ...
- Step by Step!教你如何在k3s集群上使用Traefik 2.x
本文来自边缘计算k3s社区 作者简介 Cello Spring,瑞士人.从电子起步,拥有电子工程学位.尔后开始关注计算机领域,在软件开发领域拥有多年的工作经验. Traefik是一个十分可靠的云原生动 ...
- 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 ...
- visual studio 2017 中默认无法开发 Android 8.0 及以上系统的解决方案
一般默认比较旧有两个原因,系统版本过旧,Visual Studio 版本过旧. 第一步,将windows 更新到最新版,必须是windows 10 并且更新到最新. 第二步,将visual studi ...
- Android 7.0以上版本 系统解决拍照的问题 exposed beyond app through ClipData.Item.getUri()
解决方案1: android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg e ...
- Android 5.0以上获取系统运行进程信息
在Android 5.0以上系统,调用getRunningAppProcesses 方法返回的列表为空,这是因为谷歌考虑到安全原因,已经把这个方法移除掉了, 那以后要获取系统运行的后台进程这个方法用不 ...
- 如何在Linux的桌面上创建快捷方式或启动器
如果在Linux桌面系统中你经常使用一个程序,你可能想去创建一个“桌面快捷方式”,以便于你在桌面只要点击一下快捷方式就可以启动它.虽然不少带有图形界面的程序会在安装时自动在桌面上创建快捷方式,还有一些 ...
- 如何在 Windows 和 Linux 上确定系统使用的是 MBR 分区还是 GPT 分区详细步骤!!!
在 Windows 上检查系统使用的是 MBR 分区还是 GPT 分区 点击放大镜搜索输入disk 点击打开 进入之后,右键点击你想要检查分区方案的磁盘,在右键菜单里选择属性! 在属性窗口,切换到卷, ...
随机推荐
- Thinkphp框架下封装文件下载函数
第一步:开启php_fileinfo.dll 方法:打开php.ini,将874行的;extension=php_fileinfo.dll前面的分号注释去掉即可: 第二步:控制层封装文件下载函数 fu ...
- [原创软件]Maya语言切换工具
软件主要功能: 切换Maya语言 软件界面截图: 开发环境及语言: c# .NET Framework 4.0 Visual Studio 2015 更新日志: v1.0(2016.7.20) 发布初 ...
- 关于Java中的Null
什么是Java中的Null? null在Java中是一个非常重要的概念,它最初是为了表示缺少某些东西,例如缺少用户.资源或任何东西而发明出来的.但是这也为Java程序员带来了很多麻烦,比如最常见的空指 ...
- OpenGL鼠标拖拽
前序 前段时间学习3D MAX,一对比就发现差距是相当大.我也做了一个三维展示的小软件,但是拖拽操作非常不友好,如果场景的尺寸特别大,会导致拖不动,尺寸过小会导致轻轻拖一下,模型就不知道飞哪去了.我是 ...
- MyBatis 与 Spring 整合
MyBatis-Spring 项目 目前大部分的 Java 互联网项目,都是用 Spring MVC + Spring + MyBatis 搭建平台的. 使用 Spring IoC 可以有效的管理各类 ...
- [LeetCode] Permutation in String 字符串中的全排列
Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...
- 简明shell入门
- vba打开输入文件
Sub fileCreate2() Dim folderPath, fileName, s As String Dim fs, fo, fc, f As Object folderPath = &qu ...
- [POI2016]Nim z utrudnieniem
Description A和B两个人玩游戏,一共有m颗石子,A把它们分成了n堆,每堆石子数分别为a[1],a[2],...,a[n],每轮可以选择一堆石子,取掉任意颗石子,但不能不取.谁先不能操作,谁 ...
- 【NOIP2012TG】solution
D1T1(Vigenere) 题意:给你一个原串与一个密码串,问你按照题意规则加密后的密文. 解题思路:暴力模拟. #include <stdio.h> ],c[],u1[],u2[]; ...