一张表讲透排坑:VirtualApp悬浮窗权限的Android版本适配指南 一张表讲透排坑VirtualApp悬浮窗权限的Android版本适配指南【免费下载链接】VirtualAppVirtual Engine for Android(Support 14.0 in business version)项目地址: https://gitcode.com/GitHub_Trending/vi/VirtualAppVirtualApp 是应用多开/沙盒方案子进程都跑在宿主签名下但悬浮窗权限始终是宿主级的特殊权限。这篇文章只解决一个问题Android 版本适配过程中悬浮窗权限如何一步步收紧以及一套能跑通全版本的最小改动。先搞懂机制SYSTEM_ALERT_WINDOW 是什么为什么反复被收紧SYSTEM_ALERT_WINDOW 属于特殊权限不走运行时权限流程。它的本质是允许你的 View 画到别的 App 窗口之上典型滥用场景是覆盖层诈骗所以系统要求用户必须在专门的管理页手动打开开关从 Android 6API 23起这是硬性要求。之后每个大版本都在「谁能画、何时画、画在哪」三个维度上加限制8 管窗口类型10 管后台行为12 起管服务类型14 再管位置和大小。排查沙盒问题时先想清楚一件事系统只认宿主包名子进程的身份是代理出来的。三个版本段落的规则变化对比一张表VirtualApp 悬浮窗权限的 Android 版本适配差异全部集中在下面这张表里版本区间系统变化对沙盒应用的影响关键 APIAndroid 6–7.1API 23动态权限引入SYSTEM_ALERT_WINDOW 归为特殊权限须用户在设置页手动授予能否显示完全取决于宿主的授权结果不同设备表现不一致Settings.canDrawOverlaysAndroid 8–10API 26–298 起限定用TYPE_APPLICATION_OVERLAY10 起限制后台显示悬浮窗旧窗口类型可能被拒或自动隐藏切后台必须主动收窗TYPE_APPLICATION_OVERLAYAndroid 11–14API 30–3411 要求显式canDrawOverlays校验12API 31限制前台服务类型悬浮窗需关联前台服务14API 34细化显示位置与大小控制即 Android 14 悬浮窗权限变化服务要声明有效类型窗口位置要按系统 Insets 补偿偏移Context.canDrawOverlays、startForeground6–7.1核心是这条权限不再安装即得跳设置页后必须接住「用户不开」的分支。8–10TYPE_PHONE不再推荐10 的后台限制是「前台好好的、一切走就消失」的直接原因。11–14改动大头在服务端——前台服务类型与悬浮窗要成对处理这是后两个版本踩坑最集中的地方。一份能跑通全版本的悬浮窗权限最小代码VirtualApp 适配 SYSTEM_ALERT_WINDOW第一段只需要「检查 跳系统设置页」Android 6 到 14 入口完全相同if (Build.VERSION.SDK_INT Build.VERSION_CODES.M !Settings.canDrawOverlays(context)) { Intent intent new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse(package: context.getPackageName())); startActivityForResult(intent, REQUEST_CODE_OVERLAY); return; // 回到 onActivityResult 再查一次 canDrawOverlays } // 已授权继续走下面的建窗逻辑第二段解决沙盒应用悬浮窗适配里选错窗口类型的高频坑加 View 前按版本分支即可WindowManager.LayoutParams params new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, Build.VERSION.SDK_INT Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); windowManager.addView(floatView, params);其余的 Service 样板、布局 XML、生命周期模板都可以不要能决定窗口显不显示的就是这两段。多进程的坑悬浮窗权限状态如何跨进程一致沙盒里子进程不持有独立身份权限判定挂在宿主包名下。最忌讳的做法是每个子进程各自调一次canDrawOverlays再各自缓存——进程之间没有同步状态迟早分裂。正确姿势状态收敛到 VA Server。它是唯一身份稳定、且与系统服务有直连通道的进程各沙盒进程通过 IPC 向它读写宿主授权变化时统一刷新一次。实现位置参考 VirtualApp/lib/src/main/java/com/lody/virtual/server/逻辑本身很薄private static final MapString, Boolean GRANTED new HashMap(); public static void refresh(String hostPkg, boolean granted) { GRANTED.put(hostPkg, granted); } public static boolean isGranted(String hostPkg) { return GRANTED.getOrDefault(hostPkg, false); }悬浮窗不显示自查清单⚠️ 权限没给Settings.canDrawOverlays返回 false这是系统升级后「突然不显示」的第一嫌疑。窗口类型选错8 仍在用TYPE_PHONE换TYPE_APPLICATION_OVERLAY。⚠️ 后台被系统隐藏Android 10 起切后台会收窗检查 onPause 里是否主动处理。多进程状态不一致子进程读本地旧缓存而不是向 VA Server 查询。Insets 导致位置错乱14 上没补偿 systemBars 偏移窗口被挤出或压到状态栏下。✅ 最后查 Manifest宿主是否声明了SYSTEM_ALERT_WINDOWVirtualApp 库里的位置见 lib/src/main/AndroidManifest.xml。开发流程细节可再看 doc/VADev.md。最后提醒一句前台服务类型声明还在演进上线前对照 target API 确认是否需要补新的类型后续版本跟进系统发布说明即可。【免费下载链接】VirtualAppVirtual Engine for Android(Support 14.0 in business version)项目地址: https://gitcode.com/GitHub_Trending/vi/VirtualApp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考