没有WindowManager.LayoutParams.TYPE_PHONE的粘性叠加 [英] Sticky overlay without WindowManager.LayoutParams.TYPE_PHONE

查看:150
本文介绍了没有WindowManager.LayoutParams.TYPE_PHONE的粘性叠加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

粘性,是指不会通过调用启动器意图(intent.addCategory(Intent.CATEGORY_HOME)关闭的窗口.

By sticky I mean a window that doesn't get closed by calling the launcher intent (intent.addCategory(Intent.CATEGORY_HOME).

以前,该操作是通过WindowManager.LayoutParams.TYPE_PHONE完成的,但是现在不建议使用此类型,并且会在api 28上引发异常:

Previously this was done with WindowManager.LayoutParams.TYPE_PHONE, but this type is now deprecated and throws an exception on api 28:

WindowManager $ BadTokenException ...窗口类型2002的权限被拒绝

WindowManager$BadTokenException ... permission denied for window type 2002

行为是可能的,因为Facebook的Messenger通过其聊天"Heads"来完成它,这是基于这样的假设,即由于Facebook已预先安装在许多rom上而没有获得系统应用程序许可.

The behavious is still possible since Facebook's Messenger does it with its chat "Heads", based on the assumption that facebook doesn't get system app permissions since it's pre-installed on a lot of roms.

使用WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY不起作用(即,按下主屏幕按钮也会隐藏覆盖窗口).

Using WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY doesn't work (i.e. pressing the home button also hides the overlay window).

编辑:问题是当用户单击主页"按钮/调用启动器意图时,如何将其不删除的覆盖窗口. TYPE_APPLICATION_OVERLAY不是这种情况,TYPE_PHONE是这种情况,但已弃用.

Edit: The question is how to have an overlay window that doesn't get removed when user clicks the home button / calling the launcher intent. It's not the case for TYPE_APPLICATION_OVERLAY, it was the case for TYPE_PHONE but that's deprecated.

显然,这确实适用于某些人,这是我正在运行的代码:

Edit 2: Apparently this does work for some people, this is the code I'm running:

class MyClass {

    var params: WindowManager.LayoutParams = WindowManager.LayoutParams(
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            else WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT
    ).apply {
        windowAnimations = android.R.style.Animation_Dialog
        gravity = Gravity.CENTER or Gravity.CENTER
        x = 0
        y = 0
    }
    var windowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager

    init {
        val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        rootView = layoutInflater.inflate(R.layout.view_overlay, null)
        windowManager.addView(rootView, params)
    }

}

推荐答案

解决方案:请勿将叠加层直接在其他应用上膨胀.

Solution: Don't inflate your overlay directly over other apps.

通常,使用TYPE_APPLICATION_OVERLAY仍然表现为TYPE_PHONE,我的案例的问题是,当来自另一个应用程序的活动位于前台时,我正在显示我的视图(windowManager.addView(rootView, params)),并且Android将视图附加到当前的前台活动,因此,当用户退出该活动时(例如,通过按下主屏幕按钮),系统也会从我的应用程序中删除该叠加层.对我来说,解决方案是非常具体的,我没有通用的解决方案,但是有了此信息,人们应该可以找到解决方案.

Normally, using TYPE_APPLICATION_OVERLAY still behaves as TYPE_PHONE, the issue with my case was that I was displaying my view (windowManager.addView(rootView, params)) when an activity from another app was in the foreground, and Android attaches the view to the current foreground activity, so when the user exits that activity (by pressing the home button for example), the system also kills the overlay from my app. A solution for me was very specific, I don't have a general solution but with this information should help people finding one.

这篇关于没有WindowManager.LayoutParams.TYPE_PHONE的粘性叠加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆