当请求 运行 次权限时,屏幕覆盖如何检测(并自行禁用)?

How do screen overlays detect (and disable themselves) when a run-time permission is requested?

如果应用请求用户在屏幕覆盖处于活动状态时授予 运行 时间权限,系统会发出警告,提示已检测到屏幕覆盖 - 然后用户需要手动停用屏幕覆盖,直到他们可以真正授予权限。这种从用户体验的角度来看很糟糕。

不过最近我看到了一些应用程序——尤其是 Facebook Messenger(聊天头)—— 通过简单地在请求权限时自动禁用屏幕覆盖并在授予(或未授予)后再次启用来避免这种情况。

他们是怎么做到的,我该如何重现?

我找不到任何似乎与此相关的回调或广播。

这似乎只是一个配置问题,因为它会自动使用正确的配置。

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.RGBA_8888);

以前我用过TYPE_SYSTEM_OVERLAY,但也玩过TYPE_SYSTEM_ALERT。这给了我一些无法触摸的问题,而不是 "dodge" 权限请求。或者它可以触摸,但阻止屏幕键盘。

使用此配置,视图可触摸,屏幕键盘可用,覆盖视图在请求权限时自动隐藏和显示,避免可怕的屏幕覆盖检测消息。