22

我希望能够创建一个始终位于 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>
4

3 回答 3

25
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);
于 2012-04-11T14:03:31.793 回答
5

我发现接受的答案(由 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标志被用作and的显式值int wint h。这可不好!您的视图尺寸设置为 1024*1024 - 因此它不会填满屏幕。即使您明确设置布局的宽度和高度以匹配设备的尺寸:屏幕方向更改时它们也不会更新。我们需要一种不同的方法……</p>


我发现全屏覆盖的正确结构是这样的:

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应该使用而不是TYPE_SYSTEM_ALERTAPI 级别 >=19。这是我前段时间写的一篇笔记,遗憾的是我一直无法找到引用来证实我为什么这么认为,所以请加一点盐。


额外说明(如果您正在阅读本文,您可能正在尝试制作全屏覆盖):

您的清单将需要这些权限(在此处进行说明):

<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权限。

在这里提供了我的工作 API 级别 24 应用程序的源代码,该应用程序创建了一个全屏覆盖。

于 2017-01-04T23:44:33.770 回答
-1

看看这个

在您的 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" />
于 2012-04-11T09:38:31.253 回答