如何在Android中创建始终顶级的全屏叠加活动

时间:2012-04-10 19:43:16

标签: android android-layout android-activity window

我希望能够创建一个始终位于Android显示屏前面的活动。 它应该不会收到任何输入,只需将其传递给下面的任何应用程序。像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>

3 个答案:

答案 0 :(得分: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 wm = (WindowManager) getApplicationContext()
    .getSystemService(Context.WINDOW_SERVICE);

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

答案 1 :(得分:3)

我发现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存在的构造函数如下:

enter image description here

因此,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仍然是必需的标志;如果你想绘制状态栏等装饰,这是必要的。

在API级别&gt; = 19中应使用

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY代替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应用,该应用创建了全屏叠加。

答案 2 :(得分:0)

看看这个

在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" />