以下工作代码在接收 BOOT_COMPLETED 广播的 BroadcastReceiver 中运行。
//Create a transparent, untouchable view and attach it to the system-level Window Manager
//We will force this overlay into Landscape orientation.
final View view = new View(context);
int dimension = 0;
int pixelFormat = PixelFormat.TRANSLUCENT;
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
dimension, dimension,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
pixelFormat);
params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.addView(view, params);
这旨在强制设备进入横向模式以供专门使用(不部署在 Android 市场上。这仅用于我的设备。)
我的问题是覆盖偶尔会消失。似乎没有特定的原因。它发生在应用程序中,或者有时看似随机。这会将其设置回纵向模式并导致问题。
有没有一种方法可以防止这种情况发生或观察它并在它发生时重新附加 View ?
目标设备运行的是4.0.3
最佳答案
可能发生的情况是,由于您的 View 附加在 BroadcastReceiver 中,因此应用程序本身会在其余时间“停止”,并且当 Android 决定它需要内存时,会立即停止它。这实际上可能不是原因,因为您确实有一个 View 总是显示,但由于它不是 Activity 的一部分,系统可能会以不同的方式处理它。
话虽如此,这就是我将尝试做的事情:
子类化您首选的 View 类并覆盖 onDetachedFromWindow()
,以便在调用该方法时记录/打印。如果,当这种奇怪的覆盖消失发生时 onDetachedFromWindow()
被调用,然后确定一种将 View 重新添加到 WindowManager 的方法。您可以发送广播以供 BroadcastReceiver 接收,或创建类似 Listener
的接口(interface)来分派(dispatch)分离的事件。该接口(interface)随后将由您的应用程序的长期运行部分(服务)实现。
您还可以查看当叠加层消失时 OrientationEvenListener
是否做了任何有趣的事情。
如果一切都失败了,您可以定期重新添加 View 。这不是最佳解决方案,但它确实可以确保覆盖重新出现。
上述方法也可以在长时间运行的前台服务中实现,以确保 Android 优先处理您的应用程序,不会很快杀死它。
关于android - 窗口管理器的透明 View 覆盖 "falls off"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20207304/