gpt4 book ai didi

java - 没有 WindowManager.LayoutParams.TYPE_PHONE 的粘性覆盖

转载 作者:IT老高 更新时间:2023-10-28 13:40:45 25 4
gpt4 key购买 nike

粘性是指调用启动器 Intent (intent.addCategory(Intent.CATEGORY_HOME) 时不会关闭的窗口。

以前这是使用 WindowManager.LayoutParams.TYPE_PHONE 完成的,但现在已弃用此类型并在 api 28 上引发异常:

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

这种行为仍然是可能的,因为 Facebook 的 Messenger 使用它的聊天“Heads”来实现它,这是基于 Facebook 没有获得系统应用程序权限的假设,因为它预装在很多 rom 上。

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

编辑:问题是当用户点击主页按钮/调用启动器 Intent 时,如何有一个不会被删除的覆盖窗口。 TYPE_APPLICATION_OVERLAY 不是这种情况,TYPE_PHONE 是这种情况,但已弃用。

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

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)
}

}

最佳答案

引用:https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html

TYPE_PHONE

public static final int TYPE_APPLICATION_OVERLAY

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

适用于非系统应用。请改用 TYPE_APPLICATION_OVERLAY。

窗口类型:电话。 这些是提供用户与电话交互的非应用程序窗口(特别是来电)。这些窗口通常位于所有应用程序的上方,但位于状态栏的后面。在多用户系统中显示在所有用户的窗口上。

TYPE_APPLICATION_OVERLAY

public static final int TYPE_APPLICATION_OVERLAY

窗口类型:应用程序覆盖窗口显示在所有 Activity 窗口上方(类型介于 FIRST_APPLICATION_WINDOWLAST_APPLICATION_WINDOW 之间),但在状态栏或 IME 等关键系统窗口下方。

系统可以随时更改这些窗口的位置、大小或可见性,以减少用户的视觉困惑并管理资源。

需要 Manifest.permission.SYSTEM_ALERT_WINDOW 权限。

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

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

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

我们必须在设备 Oreo 或更高版本上使用 TYPE APPLICATION OVERLAY我们已经给出了 Manoj Perumarath 的例子

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

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

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
//...other stuff
<service
android:name=".serviceClass"
android:enabled="true"
android:exported="false"/>

MainActivity

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
}

读一遍

关于java - 没有 WindowManager.LayoutParams.TYPE_PHONE 的粘性覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55251502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com