首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不带WindowManager.LayoutParams.TYPE_PHONE的粘性覆盖

不带WindowManager.LayoutParams.TYPE_PHONE的粘性覆盖
EN

Stack Overflow用户
提问于 2019-03-20 07:37:15
回答 3查看 3.5K关注 0票数 8

我所说的粘滞是指不会通过调用启动器意图(intent.addCategory(Intent.CATEGORY_HOME)来关闭的窗口。

以前这是使用WindowManager.LayoutParams.TYPE_PHONE完成的,但现在不建议使用此类型,并在API28上抛出异常:

窗口管理器$BadTokenException ...窗口类型2002的权限被拒绝

这种行为仍然是可能的,因为facebook的Messenger是通过它的聊天"Heads“来实现的,这是基于facebook没有获得系统应用权限的假设,因为它预先安装在很多roms上。

使用WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY不起作用(例如,按下主页按钮也会隐藏覆盖窗口)。

编辑:问题是如何让覆盖窗口在用户单击主页按钮/调用启动器意图时不会被移除。这不适用于TYPE_APPLICATION_OVERLAY,它适用于TYPE_PHONE,但已被弃用。

编辑2:显然这对某些人是有效的,这是我正在运行的代码:

代码语言:javascript
运行
复制
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)
    }

}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-07 01:15:37

解决方案:不要直接在其他应用程序上膨胀你的覆盖。

正常情况下,使用TYPE_APPLICATION_OVERLAY仍然像TYPE_PHONE一样,我的问题是,当来自另一个应用程序的活动在前台时,我正在显示我的视图(windowManager.addView(rootView, params)),而安卓将视图附加到当前的前台活动,所以当用户退出该活动时(例如,通过按下主页按钮),系统也会从我的应用程序中删除覆盖。对我来说,一个解决方案是非常具体的,我没有一个通用的解决方案,但有了这些信息,应该可以帮助人们找到一个。

票数 0
EN

Stack Overflow用户

发布于 2019-03-29 00:04:56

参考:https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html

代码语言:javascript
运行
复制
public static final int TYPE_APPLICATION_OVERLAY

在API级别26中,此常量已被弃用。

用于非系统应用程序。请改用TYPE_APPLICATION_OVERLAY。

窗口类型:电话。These are non-application windows providing user interaction with the phone (特别是来电)。这些窗口通常放置在所有应用程序的上方,但在状态栏之后。在多用户系统中,在所有用户的窗口中显示。

代码语言:javascript
运行
复制
public static final int TYPE_APPLICATION_OVERLAY

窗口类型:应用程序覆盖窗口显示在所有活动窗口(类型介于FIRST_APPLICATION_WINDOWLAST_APPLICATION_WINDOW之间)之上,但在关键系统窗口(如状态栏或输入法)之下。

系统可以在任何时候改变这些窗口的位置、大小或可见性,以减少用户的视觉混乱,并且还可以管理资源。

需要Manifest.permission.SYSTEM_ALERT_WINDOW权限。

代码语言:javascript
运行
复制
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

系统将调整具有此窗口类型的进程的重要性,以减少低内存杀手杀死它们的机会。

在多用户系统中,只在拥有用户的屏幕上显示。

我们必须在device Oreo上使用类型应用程序覆盖,或者稍后我们已经有了Manoj Perumarath给出的示例

您需要像这样定义窗口布局参数

代码语言:javascript
运行
复制
//if device is Oreo or latter if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

//or else
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_PHONE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

Manifest.xml

代码语言:javascript
运行
复制
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
//...other stuff
<service
android:name=".serviceClass"
android:enabled="true"
android:exported="false"/>

MainActivity

代码语言:javascript
运行
复制
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, APP_PERMISSION_REQUEST);
}
else
{
 //start service
}

读一遍

票数 2
EN

Stack Overflow用户

发布于 2019-03-28 23:45:18

Manifest中添加权限

代码语言:javascript
运行
复制
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

在launcher活动中,您应该请求canDrawOverlays权限`

代码语言:javascript
运行
复制
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && 
 !Settings.canDrawOverlays(this)) {


        //If the draw over permission is not available open the settings screen
        //to grant the permission.
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
    } else {
        initializeView();
    }

然后在你的服务中

代码语言:javascript
运行
复制
 //Inflate the floating view layout
    mFloatingView = 
    LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);

    int LAYOUT_TYPE;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        LAYOUT_TYPE = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    } else {
        LAYOUT_TYPE = WindowManager.LayoutParams.TYPE_PHONE;
    }
    //Add the view to the window.
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            LAYOUT_FLAG ,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    //Specify the view position
    params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
    params.x = 0;
    params.y = 100;

    //Add the view to the window
    mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    mWindowManager.addView(mFloatingView, params);

当用户按下Home键时,这不会被忽略。

确保您的浮动小部件被定义为service,否则当出现内存不足/配置更改之类的问题时,它将无法存活。还要在清单中注册服务

代码语言:javascript
运行
复制
   <service
            android:name=".MyWidget"
            android:enabled="true"
            android:exported="false"/>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55251502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档