没有合适的资源?快使用搜索试试~ 我知道了~
0. 前言 现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示。这个功能在很多情况下都非常有用。那么今天我们就来实现一下Android悬浮窗,以及探索一下实现悬浮窗时的易错点。 1. 实现原理 1.1 悬浮窗插入接口 在实现悬浮窗之前,我们需要知道通过什么接口,能够将一个控件放入到屏幕中去。 Android的界面绘制,都是通过WindowMananger的服务来实现的。那么,既然要实现一个能够在自身应用以外的界面上的悬浮窗,我们就要利用WindowManager来“做手脚”。 (frameworks/base/core/java/and
资源推荐
资源详情
资源评论
Android悬浮窗的实现悬浮窗的实现(易错点易错点)
0. 前言前言
现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示。这个功能在很多情况下都非常有用。那么
今天我们就来实现一下Android悬浮窗,以及探索一下实现悬浮窗时的易错点。
1. 实现原理实现原理
1.1 悬浮窗插入接口
在实现悬浮窗之前,我们需要知道通过什么接口,能够将一个控件放入到屏幕中去。
Android的界面绘制,都是通过WindowMananger的服务来实现的。那么,既然要实现一个能够在自身应用以外的界面上的悬浮窗,我们就要利用
WindowManager来“做手脚”。
(frameworks/base/core/java/android/view/WindowMananger.java)
@SystemService(Context.WINDOW_SERVICE)
public interface WindowManager extends ViewManager {
...
}
WindowManager实现了ViewManager接口,可以通过获取WINDOW_SERVICE系统服务得到。而ViewManager接口有addView方法,我们就是通过
这个方法将悬浮窗控件加入到屏幕中去。
1.2 权限设置及请求
悬浮窗需要在别的应用之上显示控件,很显然,这需要某些权限才可以。
在API Level >= 23的时候,需要在AndroidManefest.xml文件中声明权限SYSTEM_ALERT_WINDOW才能在其他应用上绘制控件。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
除了这个权限外,我们还需要在系统设置里面对本应用进行设置悬浮窗权限。该权限在应用中需要启动
Settings.ACTION_MANAGE_OVERLAY_PERMISSION来让用户手动设置权限。
startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), REQUEST_CODE);
1.3 LayoutParam设置
WindowManager的addView方法有两个参数,一个是需要加入的控件对象,另一个参数是WindowManager.LayoutParam对象。
这里需要着重说明的是LayoutParam里的type变量。这个变量是用来指定窗口类型的。在设置这个变量时,需要注意一个坑,那就是需要对不同版本
的Android系统进行适配。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
在Android 8.0之前,悬浮窗口设置可以为TYPE_PHONE,这种类型是用于提供用户交互操作的非应用窗口。
而Android 8.0对系统和API行为做了修改,包括使用SYSTEM_ALERT_WINDOW权限的应用无法再使用一下窗口类型来在其他应用和窗口上方显示
提醒窗口:
– TYPE_PHONE
– TYPE_PRIORITY_PHONE
– TYPE_SYSTEM_ALERT
– TYPE_SYSTEM_OVERLAY
– TYPE_SYSTEM_ERROR
如果需要实现在其他应用和窗口上方显示提醒窗口,那么必须该为TYPE_APPLICATION_OVERLAY的新类型。
如果在Android 8.0以上版本仍然使用TYPE_PHONE类型的悬浮窗口,则会出现如下异常信息:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f8ec928 -- permission denied for window type 2002
2. 具体实现具体实现
下面来讲解一下悬浮窗的具体实现方式。
完整的源码地址:https://github.com/dongzhong/TestForFloatingWindow
为了让悬浮窗与Activity脱离,使其在应用处于后台时悬浮窗仍然可以正常运行,这里使用Service来启动悬浮窗并做为其背后逻辑支撑。
在启动服务之前,需要先判断一下当前是否允许开启悬浮窗。
(MainActivity.java)
public void startFloatingService(View view) {
...
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(this, "当前无权限,请授权", Toast.LENGTH_SHORT);
startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);
} else {
startService(new Intent(MainActivity.this, FloatingService.class));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
startService(new Intent(MainActivity.this, FloatingService.class));
}
}
}
悬浮窗控件可以是任意的View的子类类型。这里先以一个最简单的Button来做示例。
(FloatingService.java)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
showFloatingWindow();
return super.onStartCommand(intent, flags, startId);
}
private void showFloatingWindow() {
if (Settings.canDrawOverlays(this)) {
// 获取WindowManager服务
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// 新建悬浮窗控件
Button button = new Button(getApplicationContext());
button.setText("Floating Window");
button.setBackgroundColor(Color.BLUE);
// 设置LayoutParam
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_PHONE;
}
layoutParams.format = PixelFormat.RGBA_8888;
layoutParams.width = 500;
layoutParams.height = 100;
layoutParams.x = 300;
layoutParams.y = 300;
// 将悬浮窗控件添加到WindowManager
windowManager.addView(button, layoutParams);
}
}
好了,完成了!
对,没看错,最简单的悬浮窗这就实现了。是不是很简单?来看看效果吧。
剩余8页未读,继续阅读
资源评论
weixin_38570459
- 粉丝: 3
- 资源: 931
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- apache-maven-3.6.1-bin.zip
- c593f5fc-d4a7-4b43-8ab2-51afc90f3f62
- IIR滤波器参数计算函数
- WPF树菜单拖拽功能,下级目录拖到上级目录,上级目录拖到下级目录.zip
- CDH6.3.2版本hive2.1.1修复HIVE-14706后的jar包
- 鸿蒙项目实战-天气项目(当前城市天气、温度、湿度,24h天气,未来七天天气预报,生活指数,城市选择等)
- Linux环境下oracle数据库服务器配置中文最新版本
- Linux操作系统中Oracle11g数据库安装步骤详细图解中文最新版本
- SMA中心接触件插合力量(插入力及分离力)仿真
- 变色龙记事本,有NPP功能,JSONview功能
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功