浮窗系列之越过授权使用浮窗

简介:

上一片篇文章分析了浮窗系列之Android窗口系统层次、Ativity的窗口和系统窗口的区别,这篇文章我来说说使用系统窗口来实现浮窗的一些限制,我们如何越过这些限制?

简单的浮窗实现

final WindowManager windowManager =     getWindowManager(context);
//创建自定义浮窗
 FloatView    hideDialog = new FloatView(context);
WindowManager.LayoutParams  params = new     WindowManager.LayoutParams();
//params.type 窗口类型,主要决定了窗口的层次
params.type = WindowManager.LayoutParams.TYPE_PHONE;
params.format = PixelFormat.RGBA_8888;
//params.flags 描述窗体其他属性的标记位,
//LayoutParams.FLAG_NOT_FOCUSABLE表示不能获取输入法焦点
params.flags = LayoutParams.FLAG_NOT_FOCUSABLE;
params.gravity = Gravity.LEFT | Gravity.TOP;
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.MATCH_PARENT;
//添加
windowManager.addView(hideDialog, dialogParams);

使用WindowManager.LayoutParams.TYPE_PHONE
或WindowManager.LayoutParams.TYPE_SYS_ALERT窗体类型,然后在别忘了AndroidManifest.xml文件中申明权限,这是网上关于浮窗实现的帖子千篇一律的做法,很多开发团队也是这么做的。然而在Android 4.4( api 19 )以后,手机rom就可以把这个权限动态的交给用户来选择了,例如华为、小米、oppo等一些机型。例如在华为荣耀6上,关掉《九游》App的浮窗权限,九游的浮窗就显示不了了。

九游App浮窗

于是很多产品在浮窗功能环节就加入了授权引导(针对不同的机型提示引导用户去授权),这样的体验很不友好。好在这些痛点我们是可以技术策略解决的。

窗实现越过权限使用浮窗

《交易猫》App已经越过浮窗授权,正常使用浮窗功能。

交易猫App浮窗

类型为TYPE_PHONE、TYPE_PRIORITY_PHONE、TYPE_SYSTEM_ALERT、TYPE_SYSTEM_ERROR、TYPE_SYSTEM_ERROR这些的窗口都是需要用户授权的,类型为TYPE_TOAST的不需要,然而在Android 4.4 (api 19)以下TYPE_TOAST是无法获取焦点的,具体源码分析过程可以参考文章:
[《Android悬浮窗TYPE_TOAST小结源码分析》](http://www.90159.com/2015/11/14/Android-Floating-analysis/)。于是我们就可以做一个细分流程了:首先获取系统版本如果大于等于19我们使用TYPE_TOAST,小于19我们使用TYPE_PHONE窗口类型。

_

输入法的限制

在4.4以上使用TYPE_TOAST还是有些小小的限制,如果浮窗交互中需要输入框,TYPE_TOAST和TYPE_PHONE两种类型窗体对输入法的处理还是有些区别。当我们的浮窗在横屏环境中(浮窗下面的应用是横屏的),输入法默认是全屏的,我们可以通过设置文本属性android:imeOptions=“flagNoExtractUi”来禁止输入法的全屏,同时可以设置窗体属性为adjustResize来适配调整浮窗位置防止输入法盖住输入框。

type_phone_

然而adjustResize这个属性对TYPE_TOAST类型的窗体是无效的,本人暂时没找到对应的源码佐证,如果你找到了请告诉我一下。所以如果你的浮窗交互中是需要输入文字的,就不能使用半屏幕输入法的体验了。

TYPE_TOAST_

为了最大程度的优化体验,我们使用浮窗的流程可以细化为:

_

关于浮窗授权,我们可以使用一下方法来判断是否授权:

/**
 * 判断是否开启浮窗权限,api未公开,使用反射调用
 * @return
 */
private static boolean hasAuthorFloatWin(Context context){

    if (Device.getSystemVersion() < 19){
        return false;
    }
    try {
        AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
        Class c = appOps.getClass();
        Class[] cArg = new Class[3];
        cArg[0] = int.class;
        cArg[1] = int.class;
        cArg[2] = String.class;
        Method lMethod = c.getDeclaredMethod("checkOp", cArg);
        //24是浮窗权限的标记
        return (AppOpsManager.MODE_ALLOWED == (Integer) lMethod.invoke(appOps, 24, Binder.getCallingUid(), context.getPackageName())){

    } catch(Exception e) {
       return false;
    }
}

AppOpsManager是api 19以后引入的,第三方rom可以利用它来管理权限,将某些权限交给用户来定夺,例如浮窗。详细参考官方文档:AppOpsManager
下篇文章:《浮窗系列之窗口与用户输入系统》

目录
相关文章
|
存储 Kubernetes 应用服务中间件
k8s 1.24.3版本使用nfs-provisioner4.0.0动态创建PV
k8s 1.24.3版本使用nfs-provisioner4.0.0动态创建PV
2837 0
|
JavaScript 前端开发 容器
vue element plus Layout 布局
vue element plus Layout 布局
472 0
|
canal 消息中间件 存储
手把手告诉你如何监听 MySQL binlog 实现数据变化后的实时通知!
Hello 大家好,我是阿粉。不知道大家在日常的工作中有没有遇到这样的场景,很多时候业务数据有变更需要及时加载到缓存、ES 或者发送到消息队列中通知下游服务。
7297 0
手把手告诉你如何监听 MySQL binlog 实现数据变化后的实时通知!
|
7月前
|
存储 人工智能 监控
钉钉对话机器人实现赞踩收集
本文介绍如何通过AppFlow记录钉钉AI对话卡片的用户反馈情况。首先确保已接入钉钉AI机器人,然后分三步实现:1) 修改钉钉AI消息卡片,添加点赞按钮并配置回调参数;2) 配置钉钉卡片点赞消息接收连接流,更新卡片状态;3) 设置日志收集节点,存储用户反馈数据。完成配置后,用户可在群聊中与机器人互动,并使用点踩点赞功能,反馈数据将被有效记录和分析。
608 6
钉钉对话机器人实现赞踩收集
|
11月前
|
JSON API 开发者
淘宝买家秀数据接口(taobao.item_review_show)丨淘宝 API 实时接口指南
淘宝买家秀数据接口(taobao.item_review_show)可获取买家上传的图片、视频、评论等“买家秀”内容,为潜在买家提供真实参考,帮助商家优化产品和营销策略。使用前需注册开发者账号,构建请求URL并发送GET请求,解析响应数据。调用时需遵守平台规定,保护用户隐私,确保内容真实性。
|
存储 负载均衡 算法
|
消息中间件 安全 Shell
国货之光——jdchain1.6.5测试网络部署
国货之光——jdchain1.6.5测试网络部署
425 13
|
存储 NoSQL 分布式数据库
【Flink】Flink分布式快照的原理是什么?
【4月更文挑战第21天】【Flink】Flink分布式快照的原理是什么?
|
存储 自然语言处理 架构师
聚力同行,阿里云与合作伙伴这一年
聚力同行,阿里云与合作伙伴这一年
375 0
|
安全 Java 测试技术
【开题报告】基于SpringBoot的民宿在线预定系统的设计与实现
【开题报告】基于SpringBoot的民宿在线预定系统的设计与实现
921 0
下一篇
oss云网关配置