如何在 Android 中创建始终处于顶部的全屏覆盖活动

Posted

技术标签:

【中文标题】如何在 Android 中创建始终处于顶部的全屏覆盖活动【英文标题】:How to create always-top fullscreen overlay activity in Android 【发布时间】:2012-04-23 03:11:02 【问题描述】:

我希望能够创建一个始终位于 android 显示屏前面的 Activity。 它应该不接收任何输入,只需将其传递给它下面的任何应用程序。类似于 HUD。

我能够研究我需要将基础窗口类型设置为 TYPE_SYSTEM_ALERT 但看起来 Android 忽略了我的代码 - 即使我从清单中删除 android.permission.SYSTEM_ALERT_WINDOW 权限也不会引发异常。 (必须使用此窗口类型)。当我尝试在对话框上使用 ALERT 类型时,它工作正常,但我无法将对话框变成全屏透明实体。 这是我的代码,也许缺少一些简单的东西。

public void onCreate(Bundle savedInstanceState)        
     super.onCreate(savedInstanceState);        

     requestWindowFeature(Window.FEATURE_NO_TITLE);
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
     getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);             
     getWindow().setBackgroundDrawableResource(android.R.color.transparent);
     getWindow().setFormat(PixelFormat.TRANSLUCENT);
     setContentView(R.layout.main);

半透明设置必须在xml清单中外部启用,否则它也不起作用。

 <item name="android:windowIsTranslucent">true</item>

【问题讨论】:

奥利奥怎么样 【参考方案1】:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);

WindowManager wm = (WindowManager) getApplicationContext()
    .getSystemService(Context.WINDOW_SERVICE);

ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);

【讨论】:

你的 onCreate 方法最终是什么样子的?我现在正在尝试自己测试。 ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null); @tmouse 这里的APP是什么? @tmouse 什么是 R.layout.main?是活动布局吗?还是填充视图透明? 请注意,这是一个窗口,而不是一个活动。 这里如何使用finish()。它没有用 finish() 方法关闭【参考方案2】:

我发现the accepted answer (by tmouse) 不太适合我。也许它适用于较旧的 API 级别?我使用的是 API 级别 24。

该特定答案建议:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
    PixelFormat.TRANSLUCENT
);

这有问题。 WindowManager.LayoutParams 存在的构造函数如下:

所以WindowManager.LayoutParams.FLAG_FULLSCREEN 标志被用作int wint h显式值。这可不好!您的视图尺寸设置为 1024*1024 — 因此它不会填充屏幕。即使您明确设置布局的宽度和高度以匹配设备的尺寸:它们也不会在屏幕方向改变时更新。我们需要一种不同的方法……


我发现正确的全屏叠加结构是这样的:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
    PixelFormat.TRANSLUCENT
);

这意味着我们不再明确指定宽度和高度。布局完全依赖于我们的标志。

是的,WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 仍然是必需的标志;如果你想在状态栏等装饰上绘制,这是必要的。

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY 应在 API 级别 >=19 中使用,而不是 TYPE_SYSTEM_ALERT。这是我不久前写的一篇笔记,遗憾的是我无法找到引用来证实我为什么这么认为,所以请稍加注意。


注意事项(如果您正在阅读本文,您可能正在尝试制作全屏覆盖):

您的清单将需要这些权限(解释here):

<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

我的理解是SYSTEM_ALERT_WINDOW 是实际所需的权限,但ACTION_MANAGE_OVERLAY_PERMISSION 也是必需的:它允许您在运行时请求用户授予SYSTEM_ALERT_WINDOW 权限。

我将here 源代码提供给我的工作 API 级别 24 应用程序,该应用程序创建全屏覆盖。

【讨论】:

【参考方案3】:

看看这个

在您的 AndroidManifest.xml 文件中提及它

<activity android:name=".MyActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

如果你想让你的活动全屏和透明

看看这个

<activity android:name=".MyActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />

【讨论】:

谢谢,但上面实现的只是将活动设置为全屏/透明。无论用户在做什么(启动其他应用程序、锁定手机等),我想要做的是让活动始终处于首位。 如果没有检查一下,你在 Manifest 文件中使用过&lt;uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"&gt;&lt;/uses-permission&gt; 是的,正如我所写的,我已经使用了这个,但是由于执行了上面的代码,这个权限永远不会被使用(这是错误的 - 出现这样的窗口需要权限)。

以上是关于如何在 Android 中创建始终处于顶部的全屏覆盖活动的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中创建形状三角形

在整个应用程序中始终保持 UIView 处于顶部

在 Gnome 3 下使用 Qt,Xfce 和 Unity 一个带有子窗口的全屏窗口不会停留在顶部

Qt 使应用程序在 Weston/Wayland 平台上始终处于顶部

设置 browserWindow 始终在顶部,即使其他应用程序/游戏全屏 [Electron,Windows 操作系统]

如何使用 MFC 创建全屏窗口?